diff --git a/.chronus/changes/versioning-FixVersionBug1-2024-4-21-16-34-18.md b/.chronus/changes/versioning-FixVersionBug1-2024-4-21-16-34-18.md new file mode 100644 index 0000000000..1b66d63ed6 --- /dev/null +++ b/.chronus/changes/versioning-FixVersionBug1-2024-4-21-16-34-18.md @@ -0,0 +1,8 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: fix +packages: + - "@typespec/versioning" +--- + +Using `@removed` on member types and `@added` on containing type could result in errors diff --git a/cspell.yaml b/cspell.yaml index f4a3f68563..e74bdb38fe 100644 --- a/cspell.yaml +++ b/cspell.yaml @@ -112,6 +112,7 @@ words: - unsourced - unversioned - VITE + - vitest - vsix - VSSDK - Vsts diff --git a/eng/common/scripts/Analyze-Changes.ps1 b/eng/common/scripts/Analyze-Changes.ps1 index 0b2fc42d35..c4ec209195 100644 --- a/eng/common/scripts/Analyze-Changes.ps1 +++ b/eng/common/scripts/Analyze-Changes.ps1 @@ -120,7 +120,7 @@ function Get-ActiveVariables($changes) { } # set global flag to run all if common files are changed - $runAll = $root.PathExists('eng/common') + $runAll = $root.PathExists('eng/common') -or $root.PathExists('vitest.config.ts') # set global isolated package flag to run if any eng/emiters files changed $runIsolated = $root.PathExists('eng/emitters') diff --git a/packages/http-client-csharp/emitter/src/emitter.ts b/packages/http-client-csharp/emitter/src/emitter.ts index f00d35234e..919286f0a6 100644 --- a/packages/http-client-csharp/emitter/src/emitter.ts +++ b/packages/http-client-csharp/emitter/src/emitter.ts @@ -143,7 +143,7 @@ export async function $onEmit(context: EmitContext) { const command = `dotnet --roll-forward Major ${generatorPath} ${outputFolder} ${newProjectOption} ${existingProjectOption}${debugFlag}`; Logger.getInstance().info(command); - await execAsync( + const result = await execAsync( "dotnet", [ "--roll-forward", @@ -155,20 +155,17 @@ export async function $onEmit(context: EmitContext) { debugFlag, ], { stdio: "inherit" } - ) - .then(() => { - if (!options["save-inputs"]) { - // delete - deleteFile(resolvePath(outputFolder, tspOutputFileName)); - deleteFile(resolvePath(outputFolder, configurationFileName)); - } - }) - .catch((error: any) => { - if (error.message) Logger.getInstance().info(error.message); - if (error.stderr) Logger.getInstance().error(error.stderr); - if (error.stdout) Logger.getInstance().verbose(error.stdout); - throw error; - }); + ); + if (result.exitCode !== 0) { + if (result.stderr) Logger.getInstance().error(result.stderr); + if (result.stdout) Logger.getInstance().verbose(result.stdout); + throw new Error(`Failed to generate SDK. Exit code: ${result.exitCode}`); + } + if (!options["save-inputs"]) { + // delete + deleteFile(resolvePath(outputFolder, tspOutputFileName)); + deleteFile(resolvePath(outputFolder, configurationFileName)); + } } } } diff --git a/packages/http-client-csharp/eng/CodeAnalysis.ruleset b/packages/http-client-csharp/eng/CodeAnalysis.ruleset index 620d8b708a..dc1f30e37c 100644 --- a/packages/http-client-csharp/eng/CodeAnalysis.ruleset +++ b/packages/http-client-csharp/eng/CodeAnalysis.ruleset @@ -145,8 +145,8 @@ - - + + diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ClientModelPlugin.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ClientModelPlugin.cs index 026bc0f419..959e89ac8f 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ClientModelPlugin.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ClientModelPlugin.cs @@ -2,10 +2,10 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; using System.ComponentModel.Composition; using Microsoft.Generator.CSharp.ClientModel.Expressions; using Microsoft.Generator.CSharp.Expressions; -using Microsoft.Generator.CSharp.Writers; namespace Microsoft.Generator.CSharp.ClientModel { @@ -25,6 +25,16 @@ public class ClientModelPlugin : CodeModelPlugin public override ExtensibleSnippets ExtensibleSnippets { get; } + /// + /// Returns the serialization type providers for the given model type provider. + /// + /// The model type provider. + public override IReadOnlyList GetSerializationTypeProviders(ModelTypeProvider provider) + { + // Add JSON serialization type provider + return [new MrwSerializationTypeProvider(provider)]; + } + [ImportingConstructor] public ClientModelPlugin(GeneratorContext context) : base(context) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/ClientResultExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/ClientResultExpression.cs new file mode 100644 index 0000000000..10977817b3 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/ClientResultExpression.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using Microsoft.Generator.CSharp.Expressions; + +namespace Microsoft.Generator.CSharp.ClientModel.Expressions +{ + internal sealed record ClientResultExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) + { + public ValueExpression Value => Property(nameof(ClientResult.Value)); + public BinaryDataExpression Content => throw new InvalidOperationException("Result does not have a Content property"); + public StreamExpression ContentStream => throw new InvalidOperationException("Result does not have a ContentStream property"); + + public static ClientResultExpression FromResponse(PipelineResponseExpression response) + => new(InvokeStatic(nameof(ClientResult.FromResponse), response)); + + public static ClientResultExpression FromValue(ValueExpression value, PipelineResponseExpression response) + => new(InvokeStatic(nameof(ClientResult.FromValue), value, response)); + + public static ClientResultExpression FromValue(CSharpType explicitValueType, ValueExpression value, PipelineResponseExpression response) + => new(new InvokeStaticMethodExpression(typeof(ClientResult), nameof(ClientResult.FromValue), new[] { value, response }, new[] { explicitValueType })); + + public ClientResultExpression FromValue(ValueExpression value) + => new(new InvokeStaticMethodExpression(typeof(ClientResult), nameof(ClientResult.FromValue), new[] { value, this })); + + public ClientResultExpression FromValue(CSharpType explicitValueType, ValueExpression value) + => new(new InvokeStaticMethodExpression(typeof(ClientResult), nameof(ClientResult.FromValue), new[] { value, this }, new[] { explicitValueType })); + + public PipelineResponseExpression GetRawResponse() => new(Invoke(nameof(ClientResult.GetRawResponse))); + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/MessagePipelineExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/MessagePipelineExpression.cs deleted file mode 100644 index 2cd1007154..0000000000 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/MessagePipelineExpression.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.ClientModel.Primitives.Pipeline; -using System.Collections.Generic; -using Microsoft.Generator.CSharp.Expressions; - -namespace Microsoft.Generator.CSharp.ClientModel.Expressions -{ - internal sealed record MessagePipelineExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) - { - public PipelineMessageExpression CreateMessage(RequestOptionsExpression requestContext, ValueExpression responseClassifier) => new(Invoke(nameof(MessagePipeline.CreateMessage), requestContext, responseClassifier)); - public PipelineResponseExpression ProcessMessage(TypedValueExpression message, RequestOptionsExpression? requestContext, CancellationTokenExpression? cancellationToken, bool async) - { - var arguments = new List - { - Untyped, - message, - requestContext ?? Snippets.Null - }; - - if (cancellationToken != null) - { - arguments.Add(cancellationToken); - } - - return ClientPipelineExtensionsProvider.Instance.ProcessMessage(arguments, async); - } - - public ResultExpression ProcessHeadAsBoolMessage(TypedValueExpression message, RequestOptionsExpression? requestContext, bool async) - { - var arguments = new List - { - Untyped, - message, - requestContext ?? Snippets.Null - }; - - return ClientPipelineExtensionsProvider.Instance.ProcessHeadAsBoolMessage(arguments, async); - } - } -} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineMessageExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineMessageExpression.cs index c25e460a32..2f5753cd00 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineMessageExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineMessageExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.ClientModel.Primitives; @@ -9,5 +9,9 @@ namespace Microsoft.Generator.CSharp.ClientModel.Expressions internal sealed record PipelineMessageExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) { public PipelineRequestExpression Request => new(Property(nameof(PipelineMessage.Request))); + + public PipelineResponseExpression Response => new(Property(nameof(PipelineMessage.Response))); + + public BoolExpression BufferResponse => new(Property(nameof(PipelineMessage.BufferResponse))); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineRequestExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineRequestExpression.cs index 3adf3f8f9f..4e10e79034 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineRequestExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/PipelineRequestExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -11,8 +11,8 @@ namespace Microsoft.Generator.CSharp.ClientModel.Expressions internal sealed record PipelineRequestExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) { public TypedValueExpression Uri => new FrameworkTypeExpression(typeof(Uri), Property(nameof(PipelineRequest.Uri))); - public RequestBodyExpression Content => new(Property(nameof(PipelineRequest.Content))); - public MethodBodyStatement SetMethod(string method) => new InvokeInstanceMethodStatement(Untyped, nameof(PipelineRequest.SetMethod), Literal(method)); - public MethodBodyStatement SetHeaderValue(string name, StringExpression value) => new InvokeInstanceMethodStatement(Untyped, nameof(PipelineRequest.SetHeaderValue), Literal(name), value); + public MethodBodyStatement SetMethod(string method) => Assign(Untyped.Property("Method"), Literal(method)); + public MethodBodyStatement SetHeaderValue(string name, StringExpression value) + => new InvokeInstanceMethodStatement(Untyped.Property(nameof(PipelineRequest.Headers)), nameof(PipelineRequestHeaders.Set), Literal(name), value); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/RequestBodyExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/RequestBodyExpression.cs deleted file mode 100644 index 1381d2b4f7..0000000000 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/RequestBodyExpression.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.ClientModel.Primitives; -using Microsoft.Generator.CSharp.Expressions; - -namespace Microsoft.Generator.CSharp.ClientModel.Expressions -{ - internal sealed record RequestBodyExpression(ValueExpression Untyped) : TypedValueExpression(Untyped); -} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/RequestOptionsExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/RequestOptionsExpression.cs index ff0e267439..fbf4563208 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/RequestOptionsExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/RequestOptionsExpression.cs @@ -1,7 +1,7 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.ClientModel; +using System.ClientModel.Primitives; using Microsoft.Generator.CSharp.Expressions; @@ -10,6 +10,8 @@ namespace Microsoft.Generator.CSharp.ClientModel.Expressions internal sealed record RequestOptionsExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) { public static RequestOptionsExpression FromCancellationToken() - => new(new InvokeStaticMethodExpression(null, nameof(FromCancellationToken), new ValueExpression[] { KnownParameters.CancellationTokenParameter })); + => new(new InvokeStaticMethodExpression(null, "FromCancellationToken", new ValueExpression[] { KnownParameters.CancellationTokenParameter })); + + public ValueExpression ErrorOptions => Property(nameof(RequestOptions.ErrorOptions)); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/ResultExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/ResultExpression.cs deleted file mode 100644 index 14822d6288..0000000000 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/ResultExpression.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.ClientModel; -using Microsoft.Generator.CSharp.Expressions; - -namespace Microsoft.Generator.CSharp.ClientModel.Expressions -{ - internal sealed record ResultExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) - { - public ValueExpression Value => Property(nameof(Result.Value)); - public BinaryDataExpression Content => throw new InvalidOperationException("Result does not have a Content property"); - public StreamExpression ContentStream => throw new InvalidOperationException("Result does not have a ContentStream property"); - - public static ResultExpression FromResponse(PipelineResponseExpression response) - => new(InvokeStatic(nameof(Result.FromResponse), response)); - - public static ResultExpression FromValue(ValueExpression value, PipelineResponseExpression response) - => new(InvokeStatic(nameof(Result.FromValue), value, response)); - - public static ResultExpression FromValue(CSharpType explicitValueType, ValueExpression value, PipelineResponseExpression response) - => new(new InvokeStaticMethodExpression(typeof(Result), nameof(Result.FromValue), new[] { value, response }, new[] { explicitValueType })); - - public ResultExpression FromValue(ValueExpression value) - => new(new InvokeStaticMethodExpression(typeof(Result), nameof(Result.FromValue), new[] { value, this })); - - public ResultExpression FromValue(CSharpType explicitValueType, ValueExpression value) - => new(new InvokeStaticMethodExpression(typeof(Result), nameof(Result.FromValue), new[] { value, this }, new[] { explicitValueType })); - - public PipelineResponseExpression GetRawResponse() => new(Invoke(nameof(Result.GetRawResponse))); - } -} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemJsonElementSnippets.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemJsonElementSnippets.cs deleted file mode 100644 index db5bb9150d..0000000000 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemJsonElementSnippets.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.ClientModel.Internal; -using Microsoft.Generator.CSharp.Expressions; - -namespace Microsoft.Generator.CSharp.ClientModel.Expressions -{ - internal partial class SystemExtensibleSnippets - { - private class SystemJsonElementSnippets : JsonElementSnippets - { - public override ValueExpression GetBytesFromBase64(JsonElementExpression element, string? format) => InvokeExtension(typeof(ModelSerializationExtensions), element, nameof(ModelSerializationExtensions.GetBytesFromBase64), Snippets.Literal(format)); - public override ValueExpression GetChar(JsonElementExpression element) => InvokeExtension(typeof(ModelSerializationExtensions), element, nameof(ModelSerializationExtensions.GetChar)); - public override ValueExpression GetDateTimeOffset(JsonElementExpression element, string? format) => InvokeExtension(typeof(ModelSerializationExtensions), element, nameof(ModelSerializationExtensions.GetDateTimeOffset), Snippets.Literal(format)); - public override ValueExpression GetObject(JsonElementExpression element) => InvokeExtension(typeof(ModelSerializationExtensions), element, nameof(ModelSerializationExtensions.GetObject)); - public override ValueExpression GetTimeSpan(JsonElementExpression element, string? format) => InvokeExtension(typeof(ModelSerializationExtensions), element, nameof(ModelSerializationExtensions.GetTimeSpan), Snippets.Literal(format)); - public override MethodBodyStatement ThrowNonNullablePropertyIsNull(JsonPropertyExpression property) - => new InvokeStaticMethodStatement(typeof(ModelSerializationExtensions), nameof(ModelSerializationExtensions.ThrowNonNullablePropertyIsNull), new[] { property }, CallAsExtension: true); - } - } -} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemModelSnippets.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemModelSnippets.cs index 396b91ffa0..210afb97cc 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemModelSnippets.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemModelSnippets.cs @@ -1,8 +1,6 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.ClientModel.Internal; using System.ClientModel.Primitives; using Microsoft.Generator.CSharp.Expressions; @@ -12,21 +10,6 @@ internal partial class SystemExtensibleSnippets { internal class SystemModelSnippets : ModelSnippets { - public override CSharpMethod BuildConversionToRequestBodyMethod(MethodSignatureModifiers modifiers) - { - return new CSharpMethod - ( - new MethodSignature(ClientModelPlugin.Instance.Configuration.ApiTypes.ToRequestContentName, null, $"Convert into a {nameof(Utf8JsonRequestBody)}.", modifiers, typeof(RequestBody), null, Array.Empty()), - new[] - { - Snippets.Extensible.RestOperations.DeclareContentWithUtf8JsonWriter(out var requestContent, out var writer), - writer.WriteObjectValue(Snippets.This), - Snippets.Return(requestContent) - }, - "default" - ); - } - public override CSharpMethod BuildFromOperationResponseMethod(TypeProvider typeProvider, MethodSignatureModifiers modifiers) { var result = new Parameter("response", $"The result to deserialize the model from.", typeof(PipelineResponse), null, ValidationType.None, null); @@ -41,8 +24,6 @@ public override CSharpMethod BuildFromOperationResponseMethod(TypeProvider typeP "default" ); } - - public override TypedValueExpression InvokeToRequestBodyMethod(TypedValueExpression model) => new RequestBodyExpression(model.Invoke("ToRequestBody")); } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs index 0cb7582719..d9c572ec45 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs @@ -16,24 +16,24 @@ internal partial class SystemExtensibleSnippets private class SystemRestOperationsSnippets : RestOperationsSnippets { public override StreamExpression GetContentStream(TypedValueExpression result) - => new ResultExpression(result).GetRawResponse().ContentStream; + => new ClientResultExpression(result).GetRawResponse().ContentStream; public override TypedValueExpression GetTypedResponseFromValue(TypedValueExpression value, TypedValueExpression result) { - return ResultExpression.FromValue(value, GetRawResponse(result)); + return ClientResultExpression.FromValue(value, GetRawResponse(result)); } public override TypedValueExpression GetTypedResponseFromModel(TypeProvider typeProvider, TypedValueExpression result) { var response = GetRawResponse(result); var model = new InvokeStaticMethodExpression(typeProvider.Type, ClientModelPlugin.Instance.Configuration.ApiTypes.FromResponseName, new[] { response }); - return ResultExpression.FromValue(model, response); + return ClientResultExpression.FromValue(model, response); } public override TypedValueExpression GetTypedResponseFromEnum(EnumType enumType, TypedValueExpression result) { var response = GetRawResponse(result); - return ResultExpression.FromValue(EnumExpression.ToEnum(enumType, response.Content.ToObjectFromJson(typeof(string))), response); + return ClientResultExpression.FromValue(EnumExpression.ToEnum(enumType, response.Content.ToObjectFromJson(typeof(string))), response); } public override TypedValueExpression GetTypedResponseFromBinaryData(Type responseType, TypedValueExpression result, string? contentType = null) @@ -41,11 +41,11 @@ public override TypedValueExpression GetTypedResponseFromBinaryData(Type respons var rawResponse = GetRawResponse(result); if (responseType == typeof(string) && contentType != null && FormattableStringHelpers.ToMediaType(contentType) == BodyMediaType.Text) { - return ResultExpression.FromValue(rawResponse.Content.InvokeToString(), rawResponse); + return ClientResultExpression.FromValue(rawResponse.Content.InvokeToString(), rawResponse); } return responseType == typeof(BinaryData) - ? ResultExpression.FromValue(rawResponse.Content, rawResponse) - : ResultExpression.FromValue(rawResponse.Content.ToObjectFromJson(responseType), rawResponse); + ? ClientResultExpression.FromValue(rawResponse.Content, rawResponse) + : ClientResultExpression.FromValue(rawResponse.Content.ToObjectFromJson(responseType), rawResponse); } public override MethodBodyStatement DeclareHttpMessage(MethodSignatureBase createRequestMethodSignature, out TypedValueExpression message) @@ -57,30 +57,16 @@ public override MethodBodyStatement DeclareHttpMessage(MethodSignatureBase creat public override MethodBodyStatement DeclareContentWithUtf8JsonWriter(out TypedValueExpression content, out Utf8JsonWriterExpression writer) { - var contentVar = new VariableReference(typeof(Utf8JsonRequestBody), "content"); + var contentVar = new VariableReference(typeof(BinaryContent), "content"); content = contentVar; - writer = new Utf8JsonRequestBodyExpression(content).JsonWriter; - return Snippets.Var(contentVar, Snippets.New.Instance(typeof(Utf8JsonRequestBody))); + writer = new Utf8JsonWriterExpression(content.Property("JsonWriter")); + return Snippets.Var(contentVar, Snippets.New.Instance(typeof(BinaryContent))); } - public override MethodBodyStatement InvokeServiceOperationCallAndReturnHeadAsBool(TypedValueExpression pipeline, TypedValueExpression message, TypedValueExpression clientDiagnostics, bool async) - { - var resultVar = new VariableReference(typeof(NullableResult), "result"); - var result = new ResultExpression(resultVar); - return new MethodBodyStatement[] - { - Snippets.Var(resultVar, new MessagePipelineExpression(pipeline).ProcessHeadAsBoolMessage(message, new RequestOptionsExpression(KnownParameters.RequestContext), async)), - Snippets.Return(ResultExpression.FromValue(result.Value, result.GetRawResponse())) - }; - } - - public override TypedValueExpression InvokeServiceOperationCall(TypedValueExpression pipeline, TypedValueExpression message, bool async) - => ResultExpression.FromResponse(new MessagePipelineExpression(pipeline).ProcessMessage(message, new RequestOptionsExpression(KnownParameters.RequestContext), null, async)); - private static PipelineResponseExpression GetRawResponse(TypedValueExpression result) => result.Type.Equals(typeof(PipelineResponse)) ? new PipelineResponseExpression(result) - : new ResultExpression(result).GetRawResponse(); + : new ClientResultExpression(result).GetRawResponse(); } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.cs index 82c32c036f..98004bbab3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemExtensibleSnippets.cs @@ -1,14 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; using Microsoft.Generator.CSharp.Expressions; namespace Microsoft.Generator.CSharp.ClientModel.Expressions { internal partial class SystemExtensibleSnippets : ExtensibleSnippets { - public override JsonElementSnippets JsonElement { get; } = new SystemJsonElementSnippets(); public override RestOperationsSnippets RestOperations { get; } = new SystemRestOperationsSnippets(); public override ModelSnippets Model { get; } = new SystemModelSnippets(); } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemSnippets.Serializations.JsonFormat.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemSnippets.Serializations.JsonFormat.cs new file mode 100644 index 0000000000..eb23798001 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/SystemSnippets.Serializations.JsonFormat.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Generator.CSharp.Expressions; + +namespace Microsoft.Generator.CSharp.ClientModel.Expressions +{ + internal static partial class SystemSnippets + { + internal static StringExpression JsonFormatSerialization = Snippets.Literal("J"); + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/Utf8JsonRequestBodyExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/Utf8JsonRequestBodyExpression.cs deleted file mode 100644 index d1cd698447..0000000000 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Expressions/Utf8JsonRequestBodyExpression.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.ClientModel.Internal; -using Microsoft.Generator.CSharp.Expressions; - -namespace Microsoft.Generator.CSharp.ClientModel.Expressions -{ - internal sealed record Utf8JsonRequestBodyExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) - { - public Utf8JsonWriterExpression JsonWriter => new(Property(nameof(Utf8JsonRequestBody.JsonWriter))); - } -} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Models/Types/ClientPipelineExtensionsProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Models/Types/ClientPipelineExtensionsProvider.cs index 2f16cb24d0..a9843fe598 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Models/Types/ClientPipelineExtensionsProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Models/Types/ClientPipelineExtensionsProvider.cs @@ -1,9 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using Microsoft.Generator.CSharp.Expressions; -using System.ClientModel.Primitives.Pipeline; using System.ClientModel.Primitives; using System.ClientModel; using Microsoft.Generator.CSharp.ClientModel.Expressions; @@ -35,7 +34,7 @@ private ClientPipelineExtensionsProvider() { Name = "ClientPipelineExtensions"; DeclarationModifiers = TypeSignatureModifiers.Internal | TypeSignatureModifiers.Static; - _pipelineParam = new Parameter("pipeline", null, typeof(Pipeline), null, ValidationType.None, null); + _pipelineParam = new Parameter("pipeline", null, typeof(ClientPipeline), null, ValidationType.None, null); _messageParam = new Parameter("message", null, typeof(PipelineMessage), null, ValidationType.None, null); _requestContextParam = new Parameter("requestContext", null, typeof(RequestOptions), null, ValidationType.None, null); _pipeline = new ParameterReference(_pipelineParam); @@ -49,7 +48,7 @@ internal PipelineResponseExpression ProcessMessage(IReadOnlyList arguments, bool isAsync) + internal ClientResultExpression ProcessHeadAsBoolMessage(IReadOnlyList arguments, bool isAsync) { return new(new InvokeStaticMethodExpression(Type, isAsync ? _processHeadAsBoolMessageAsync : _processHeadAsBoolMessage, arguments, CallAsExtension: true, CallAsAsync: isAsync)); } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Models/Types/MrwSerializationTypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Models/Types/MrwSerializationTypeProvider.cs new file mode 100644 index 0000000000..b3308c88d0 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Models/Types/MrwSerializationTypeProvider.cs @@ -0,0 +1,170 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel.Primitives; +using System.Linq; +using System.Text.Json; +using Microsoft.Generator.CSharp.ClientModel.Expressions; +using Microsoft.Generator.CSharp.Expressions; + +namespace Microsoft.Generator.CSharp.ClientModel +{ + /// + /// This class provides the set of serialization models, methods, and interfaces for a given model. + /// + internal sealed class MrwSerializationTypeProvider : TypeProvider + { + private readonly Parameter SerializationOptionsParameter = + new("options", null, typeof(ModelReaderWriterOptions), null, ValidationType.None, null); + private readonly CSharpType _iJsonModelTInterface; + private readonly CSharpType? _iJsonModelObjectInterface; + private readonly CSharpType _iPersistableModelTInterface; + private readonly CSharpType? _iPersistableModelObjectInterface; + private ModelTypeProvider _model; + + public MrwSerializationTypeProvider(ModelTypeProvider model) : base(null) + { + _model = model; + Name = model.Name; + // Initialize the serialization interfaces + _iJsonModelTInterface = new CSharpType(typeof(IJsonModel<>), _model.Type); + _iJsonModelObjectInterface = _model.IsStruct ? (CSharpType)typeof(IJsonModel) : null; + _iPersistableModelTInterface = new CSharpType(typeof(IPersistableModel<>), _model.Type); + _iPersistableModelObjectInterface = _model.IsStruct ? (CSharpType)typeof(IPersistableModel) : null; + } + + public override string Name { get; } + + /// + /// Builds the serialization methods for the model. If the serialization supports JSON, it will build the JSON serialization methods. + /// + /// A list of serialization and deserialization methods for the model. + protected override CSharpMethod[] BuildMethods() + { + // TO-DO: Add deserialization methods https://github.com/microsoft/typespec/issues/3330 + + return new CSharpMethod[] + { + // Add JSON serialization methods + BuildJsonModelWriteMethod(), + BuildJsonModelCreateMethod(), + // Add IModel methods + BuildIModelWriteMethod(), + BuildIModelCreateMethod(), + BuildIModelGetFormatFromOptionsMethod() + }; + } + + /// + /// Builds the types that the model type serialization implements. + /// + /// An array of types that the model implements. + protected override CSharpType[] BuildImplements() + { + int interfaceCount = _iJsonModelObjectInterface != null ? 2 : 1; + CSharpType[] interfaces = new CSharpType[interfaceCount]; + interfaces[0] = _iJsonModelTInterface; + + if (_iJsonModelObjectInterface != null) + { + interfaces[1] = _iJsonModelObjectInterface; + } + + return interfaces; + } + + /// + /// Builds the JSON serialization write method for the model. + /// + internal CSharpMethod BuildJsonModelWriteMethod() + { + Parameter utf8JsonWriterParameter = new("writer", null, typeof(Utf8JsonWriter), null, ValidationType.None, null); + // void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + return new CSharpMethod + ( + new MethodSignature(nameof(IJsonModel.Write), null, null, MethodSignatureModifiers.None, null, null, new[] { utf8JsonWriterParameter, SerializationOptionsParameter }, ExplicitInterface: _iJsonModelTInterface), + // TO-DO: Add body for json properties' serialization https://github.com/microsoft/typespec/issues/3330 + Snippets.EmptyStatement + ); + } + + /// + /// Builds the JSON serialization create method for the model. + /// + internal CSharpMethod BuildJsonModelCreateMethod() + { + Parameter utf8JsonReaderParameter = new("reader", null, typeof(Utf8JsonReader), null, ValidationType.None, null, IsRef: true); + // T IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + var typeOfT = GetModelArgumentType(_iJsonModelTInterface); + return new CSharpMethod + ( + new MethodSignature(nameof(IJsonModel.Create), null, null, MethodSignatureModifiers.None, typeOfT, null, new[] { utf8JsonReaderParameter, SerializationOptionsParameter }, ExplicitInterface: _iJsonModelTInterface), + // TO-DO: Call the base model ctor for now until the model properties are serialized https://github.com/microsoft/typespec/issues/3330 + Snippets.Return(new NewInstanceExpression(typeOfT, Array.Empty())) + ); + } + + /// + /// Builds the I model write method. + /// + internal CSharpMethod BuildIModelWriteMethod() + { + // BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + var returnType = typeof(BinaryData); + return new CSharpMethod + ( + new MethodSignature(nameof(IPersistableModel.Write), null, null, MethodSignatureModifiers.None, returnType, null, new[] { SerializationOptionsParameter }, ExplicitInterface: _iPersistableModelTInterface), + // TO-DO: Call the base model ctor for now until the model properties are serialized https://github.com/microsoft/typespec/issues/3330 + Snippets.Return(new NewInstanceExpression(returnType, new ValueExpression[] { new StringLiteralExpression(_iPersistableModelTInterface.Name, false) })) + ); + } + + /// + /// Builds the I model create method. + /// + internal CSharpMethod BuildIModelCreateMethod() + { + Parameter dataParameter = new("data", null, typeof(BinaryData), null, ValidationType.None, null); + // IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + var typeOfT = GetModelArgumentType(_iPersistableModelTInterface); + return new CSharpMethod + ( + new MethodSignature(nameof(IPersistableModel.Create), null, null, MethodSignatureModifiers.None, typeOfT, null, new[] { dataParameter, SerializationOptionsParameter }, ExplicitInterface: _iPersistableModelTInterface), + // TO-DO: Call the base model ctor for now until the model properties are serialized https://github.com/microsoft/typespec/issues/3330 + Snippets.Return(new NewInstanceExpression(typeOfT, Array.Empty())) + ); + } + + /// + /// Builds the I model GetFormatFromOptions method. + /// + internal CSharpMethod BuildIModelGetFormatFromOptionsMethod() + { + ValueExpression jsonWireFormat = SystemSnippets.JsonFormatSerialization; + // ModelReaderWriterFormat IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) + return new CSharpMethod + ( + new MethodSignature(nameof(IPersistableModel.GetFormatFromOptions), null, null, MethodSignatureModifiers.None, typeof(string), null, new[] { SerializationOptionsParameter }, ExplicitInterface: _iPersistableModelTInterface), + jsonWireFormat + ); + } + + /// + /// Attempts to get the model argument type from the model interface. + /// + /// The that represents the model interface. + /// The first argument type of . + /// Thrown if the contains no arguments. + private CSharpType GetModelArgumentType(CSharpType modelInterface) + { + var interfaceArgs = modelInterface.Arguments; + if (!interfaceArgs.Any()) + { + throw new InvalidOperationException($"Expected at least 1 argument for {modelInterface}, but found none."); + } + + return interfaceArgs[0]; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Properties/AssemblyInfo.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..aa3833f452 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.Generator.CSharp.ClientModel.Tests")] diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ScmTypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ScmTypeFactory.cs index a612239d9b..b0cd3637b2 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ScmTypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/ScmTypeFactory.cs @@ -37,43 +37,43 @@ internal class ScmTypeFactory : TypeFactory : new CSharpType(typeof(object), model.IsNullable).WithNullable(inputType.IsNullable), InputPrimitiveType primitiveType => primitiveType.Kind switch { - InputTypeKind.BinaryData => new CSharpType(typeof(BinaryData), inputType.IsNullable), - InputTypeKind.Boolean => new CSharpType(typeof(bool), inputType.IsNullable), - InputTypeKind.BytesBase64Url => new CSharpType(typeof(BinaryData), inputType.IsNullable), - InputTypeKind.Bytes => new CSharpType(typeof(BinaryData), inputType.IsNullable), - InputTypeKind.ContentType => new CSharpType(typeof(HttpContent), inputType.IsNullable), - InputTypeKind.Date => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), - InputTypeKind.DateTime => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), - InputTypeKind.DateTimeISO8601 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), - InputTypeKind.DateTimeRFC1123 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), - InputTypeKind.DateTimeRFC3339 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), - InputTypeKind.DateTimeRFC7231 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), - InputTypeKind.DateTimeUnix => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), - InputTypeKind.Decimal => new CSharpType(typeof(decimal), inputType.IsNullable), - InputTypeKind.Decimal128 => new CSharpType(typeof(decimal), inputType.IsNullable), - InputTypeKind.DurationISO8601 => new CSharpType(typeof(TimeSpan), inputType.IsNullable), - InputTypeKind.DurationSeconds => new CSharpType(typeof(TimeSpan), inputType.IsNullable), - InputTypeKind.DurationSecondsFloat => new CSharpType(typeof(TimeSpan), inputType.IsNullable), - InputTypeKind.DurationConstant => new CSharpType(typeof(TimeSpan), inputType.IsNullable), - InputTypeKind.ETag => new CSharpType(typeof(EntityTagHeaderValue), inputType.IsNullable), - InputTypeKind.Float32 => new CSharpType(typeof(float), inputType.IsNullable), - InputTypeKind.Float64 => new CSharpType(typeof(double), inputType.IsNullable), - InputTypeKind.Float128 => new CSharpType(typeof(decimal), inputType.IsNullable), - InputTypeKind.Guid => new CSharpType(typeof(Guid), inputType.IsNullable), - InputTypeKind.SByte => new CSharpType(typeof(sbyte), inputType.IsNullable), - InputTypeKind.Byte => new CSharpType(typeof(byte), inputType.IsNullable), - InputTypeKind.Int32 => new CSharpType(typeof(int), inputType.IsNullable), - InputTypeKind.Int64 => new CSharpType(typeof(long), inputType.IsNullable), - InputTypeKind.SafeInt => new CSharpType(typeof(long), inputType.IsNullable), - InputTypeKind.IPAddress => new CSharpType(typeof(IPAddress), inputType.IsNullable), - InputTypeKind.RequestMethod => new CSharpType(typeof(HttpMethod), inputType.IsNullable), - InputTypeKind.Stream => new CSharpType(typeof(Stream), inputType.IsNullable), - InputTypeKind.String => new CSharpType(typeof(string), inputType.IsNullable), - InputTypeKind.Time => new CSharpType(typeof(TimeSpan), inputType.IsNullable), - InputTypeKind.Uri => new CSharpType(typeof(Uri), inputType.IsNullable), + InputPrimitiveTypeKind.BinaryData => new CSharpType(typeof(BinaryData), inputType.IsNullable), + InputPrimitiveTypeKind.Boolean => new CSharpType(typeof(bool), inputType.IsNullable), + InputPrimitiveTypeKind.BytesBase64Url => new CSharpType(typeof(BinaryData), inputType.IsNullable), + InputPrimitiveTypeKind.Bytes => new CSharpType(typeof(BinaryData), inputType.IsNullable), + InputPrimitiveTypeKind.ContentType => new CSharpType(typeof(HttpContent), inputType.IsNullable), + InputPrimitiveTypeKind.Date => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), + InputPrimitiveTypeKind.DateTime => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), + InputPrimitiveTypeKind.DateTimeISO8601 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), + InputPrimitiveTypeKind.DateTimeRFC1123 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), + InputPrimitiveTypeKind.DateTimeRFC3339 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), + InputPrimitiveTypeKind.DateTimeRFC7231 => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), + InputPrimitiveTypeKind.DateTimeUnix => new CSharpType(typeof(DateTimeOffset), inputType.IsNullable), + InputPrimitiveTypeKind.Decimal => new CSharpType(typeof(decimal), inputType.IsNullable), + InputPrimitiveTypeKind.Decimal128 => new CSharpType(typeof(decimal), inputType.IsNullable), + InputPrimitiveTypeKind.DurationISO8601 => new CSharpType(typeof(TimeSpan), inputType.IsNullable), + InputPrimitiveTypeKind.DurationSeconds => new CSharpType(typeof(TimeSpan), inputType.IsNullable), + InputPrimitiveTypeKind.DurationSecondsFloat => new CSharpType(typeof(TimeSpan), inputType.IsNullable), + InputPrimitiveTypeKind.DurationConstant => new CSharpType(typeof(TimeSpan), inputType.IsNullable), + InputPrimitiveTypeKind.ETag => new CSharpType(typeof(EntityTagHeaderValue), inputType.IsNullable), + InputPrimitiveTypeKind.Float32 => new CSharpType(typeof(float), inputType.IsNullable), + InputPrimitiveTypeKind.Float64 => new CSharpType(typeof(double), inputType.IsNullable), + InputPrimitiveTypeKind.Float128 => new CSharpType(typeof(decimal), inputType.IsNullable), + InputPrimitiveTypeKind.Guid => new CSharpType(typeof(Guid), inputType.IsNullable), + InputPrimitiveTypeKind.SByte => new CSharpType(typeof(sbyte), inputType.IsNullable), + InputPrimitiveTypeKind.Byte => new CSharpType(typeof(byte), inputType.IsNullable), + InputPrimitiveTypeKind.Int32 => new CSharpType(typeof(int), inputType.IsNullable), + InputPrimitiveTypeKind.Int64 => new CSharpType(typeof(long), inputType.IsNullable), + InputPrimitiveTypeKind.SafeInt => new CSharpType(typeof(long), inputType.IsNullable), + InputPrimitiveTypeKind.IPAddress => new CSharpType(typeof(IPAddress), inputType.IsNullable), + InputPrimitiveTypeKind.RequestMethod => new CSharpType(typeof(HttpMethod), inputType.IsNullable), + InputPrimitiveTypeKind.Stream => new CSharpType(typeof(Stream), inputType.IsNullable), + InputPrimitiveTypeKind.String => new CSharpType(typeof(string), inputType.IsNullable), + InputPrimitiveTypeKind.Time => new CSharpType(typeof(TimeSpan), inputType.IsNullable), + InputPrimitiveTypeKind.Uri => new CSharpType(typeof(Uri), inputType.IsNullable), _ => new CSharpType(typeof(object), inputType.IsNullable), }, - InputGenericType genericType => new CSharpType(genericType.Type, CreateCSharpType(genericType.ArgumentType)).WithNullable(inputType.IsNullable), + InputGenericType genericType => new CSharpType(genericType.Type, genericType.Arguments.Select(CreateCSharpType).ToArray(), genericType.IsNullable), InputIntrinsicType { Kind: InputIntrinsicTypeKind.Unknown } => typeof(BinaryData), _ => throw new Exception("Unknown type") }; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/SystemApiTypes.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/SystemApiTypes.cs index 6d98e521c7..36c952f087 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/SystemApiTypes.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/SystemApiTypes.cs @@ -1,10 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using System.ClientModel; -using System.ClientModel.Internal; -using System.ClientModel.Primitives.Pipeline; using System.ClientModel.Primitives; using Microsoft.Generator.CSharp.Expressions; @@ -15,46 +13,40 @@ namespace Microsoft.Generator.CSharp.ClientModel /// internal class SystemApiTypes : ApiTypes { - public override Type ChangeTrackingListType => typeof(OptionalList<>); - public override Type ChangeTrackingDictionaryType => typeof(OptionalDictionary<,>); - public override Type ResponseType => typeof(Result); - public override Type ResponseOfTType => typeof(Result<>); + public override Type ResponseType => typeof(ClientResult); + public override Type ResponseOfTType => typeof(ClientResult<>); public override string ResponseParameterName => "result"; public override string ContentStreamName => $"{GetRawResponseName}().{nameof(PipelineResponse.ContentStream)}"; public override string StatusName => $"{GetRawResponseName}().{nameof(PipelineResponse.Status)}"; - public override string GetRawResponseName => nameof(Result.GetRawResponse); + public override string GetRawResponseName => nameof(ClientResult.GetRawResponse); - public override Type HttpPipelineType => typeof(MessagePipeline); - public override Type PipelineExtensionsType => typeof(PipelineProtocolExtensions); - public override string HttpPipelineCreateMessageName => nameof(MessagePipeline.CreateMessage); + public override Type HttpPipelineType => typeof(ClientPipeline); + public override string HttpPipelineCreateMessageName => nameof(ClientPipeline.CreateMessage); public override Type HttpMessageType => typeof(PipelineMessage); public override string HttpMessageResponseName => nameof(PipelineMessage.Response); public override string HttpMessageResponseStatusName => nameof(PipelineResponse.Status); - public override Type ClientDiagnosticsType => typeof(TelemetrySource); - public override string ClientDiagnosticsCreateScopeName => nameof(TelemetrySource.CreateSpan); - public override Type ClientOptionsType => typeof(RequestOptions); public override Type RequestContextType => typeof(RequestOptions); public override Type BearerAuthenticationPolicyType => throw new NotSupportedException("Bearer authentication is not supported in non-branded libraries yet"); - public override Type KeyCredentialType => typeof(KeyCredential); - public override Type HttpPipelineBuilderType => typeof(MessagePipeline); - public override Type KeyCredentialPolicyType => typeof(KeyCredentialPolicy); + public override Type KeyCredentialType => typeof(ApiKeyCredential); + public override Type HttpPipelineBuilderType => typeof(ClientPipeline); + public override Type KeyCredentialPolicyType => typeof(ApiKeyAuthenticationPolicy); public override FormattableString GetHttpPipelineBearerString(string pipelineField, string optionsVariable, string credentialVariable, string scopesParamName) => $"{pipelineField} = {HttpPipelineBuilderType}.Build({optionsVariable}, new {BearerAuthenticationPolicyType}({credentialVariable}, {new CodeWriterDeclaration(scopesParamName)}));"; - public override FormattableString GetHttpPipelineClassifierString(string pipelineField, string optionsVariable, FormattableString perCallPolicies, FormattableString perRetryPolicies) - => $"{pipelineField:I} = {typeof(MessagePipeline)}.{nameof(MessagePipeline.Create)}({optionsVariable:I}, {perRetryPolicies}, {perCallPolicies});"; + public override FormattableString GetHttpPipelineClassifierString(string pipelineField, string optionsVariable, FormattableString perCallPolicies, FormattableString perRetryPolicies, FormattableString beforeTransportPolicies) + => $"{pipelineField:I} = {typeof(ClientPipeline)}.{nameof(ClientPipeline.Create)}({optionsVariable:I}, {perCallPolicies}, {perRetryPolicies}, {beforeTransportPolicies});"; - public override Type HttpPipelinePolicyType => typeof(IPipelinePolicy); + public override Type HttpPipelinePolicyType => typeof(PipelinePolicy); public override string HttpMessageRequestName => nameof(PipelineMessage.Request); public override FormattableString GetSetMethodString(string requestName, string method) { - return $"{requestName}.{nameof(PipelineRequest.SetMethod)}(\"{method}\");"; + return $"{requestName}.{nameof(PipelineRequest.Method)}(\"{method}\");"; } private string GetHttpMethodName(string method) @@ -63,43 +55,24 @@ private string GetHttpMethodName(string method) } public override FormattableString GetSetUriString(string requestName, string uriName) - => $"{requestName}.Uri = {uriName}.{nameof(RequestUri.ToUri)}();"; + => $"{requestName}.Uri = {uriName}.ToUri();"; public override FormattableString GetSetContentString(string requestName, string contentName) => $"{requestName}.Content = {contentName};"; - public override Type RequestUriType => typeof(RequestUri); - public override Type RequestContentType => typeof(RequestBody); + public override Type RequestContentType => typeof(BinaryContent); public override string CancellationTokenName => nameof(RequestOptions.CancellationToken); public override string ToRequestContentName => "ToRequestBody"; - public override string RequestContentCreateName => nameof(RequestBody.CreateFromStream); - - public override Type IUtf8JsonSerializableType => typeof(IUtf8JsonWriteable); + public override string RequestContentCreateName => nameof(BinaryContent.Create); public override Type IXmlSerializableType => throw new NotSupportedException("Xml serialization is not supported in non-branded libraries yet"); - public override string IUtf8JsonSerializableWriteName => nameof(IUtf8JsonWriteable.Write); - - public override Type Utf8JsonWriterExtensionsType => typeof(ModelSerializationExtensions); - public override string Utf8JsonWriterExtensionsWriteObjectValueName => nameof(ModelSerializationExtensions.WriteObjectValue); - public override string Utf8JsonWriterExtensionsWriteNumberValueName => nameof(ModelSerializationExtensions.WriteNumberValue); - public override string Utf8JsonWriterExtensionsWriteStringValueName => nameof(ModelSerializationExtensions.WriteStringValue); - public override string Utf8JsonWriterExtensionsWriteBase64StringValueName => nameof(ModelSerializationExtensions.WriteBase64StringValue); - - public override Type OptionalType => typeof(OptionalProperty); - public override Type OptionalPropertyType => typeof(OptionalProperty<>); - - public override string OptionalIsCollectionDefinedName => nameof(OptionalProperty.IsCollectionDefined); - public override string OptionalIsDefinedName => nameof(OptionalProperty.IsDefined); - public override string OptionalToDictionaryName => nameof(OptionalProperty.ToDictionary); - public override string OptionalToListName => nameof(OptionalProperty.ToList); - public override string OptionalToNullableName => nameof(OptionalProperty.ToNullable); - public override Type RequestFailedExceptionType => typeof(MessageFailedException); + public override Type RequestFailedExceptionType => typeof(ClientResultException); - public override string ResponseClassifierIsErrorResponseName => nameof(ResponseErrorClassifier.IsErrorResponse); + public override string ResponseClassifierIsErrorResponseName => nameof(PipelineMessageClassifier.TryClassify); - public override Type ResponseClassifierType => typeof(ResponseErrorClassifier); - public override Type StatusCodeClassifierType => typeof(StatusResponseClassifier); + public override Type ResponseClassifierType => typeof(PipelineMessageClassifier); + public override Type StatusCodeClassifierType => typeof(PipelineMessageClassifier); public override ValueExpression GetCreateFromStreamSampleExpression(ValueExpression freeFormObjectExpression) => new InvokeStaticMethodExpression(ClientModelPlugin.Instance.Configuration.ApiTypes.RequestContentType, ClientModelPlugin.Instance.Configuration.ApiTypes.RequestContentCreateName, new[] { BinaryDataExpression.FromObjectAsJson(freeFormObjectExpression).ToStream() }); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Microsoft.Generator.CSharp.ClientModel.Tests.csproj b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Microsoft.Generator.CSharp.ClientModel.Tests.csproj new file mode 100644 index 0000000000..bad2e47a16 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Microsoft.Generator.CSharp.ClientModel.Tests.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + false + true + + + + + + + + + + + + + + + + PreserveNewest + + + diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/MrwSerializationTypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/MrwSerializationTypeProviderTests.cs new file mode 100644 index 0000000000..c4ae1049b0 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/MrwSerializationTypeProviderTests.cs @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Generator.CSharp.Input; +using Moq; +using NUnit.Framework; +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace Microsoft.Generator.CSharp.ClientModel.Tests +{ + internal class MrwSerializationTypeProviderTests + { + private readonly string _mocksFolder = "mocks"; + private FieldInfo? _mockPlugin; + + [SetUp] + public void Setup() + { + string configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder); + // initialize the mock singleton instance of the plugin + _mockPlugin = typeof(CodeModelPlugin).GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic); + // invoke the load method with the config file path + var loadMethod = typeof(Configuration).GetMethod("Load", BindingFlags.Static | BindingFlags.NonPublic); + object[] parameters = new object[] { configFilePath, null! }; + var config = loadMethod?.Invoke(null, parameters); + var mockGeneratorContext = new Mock(config!); + var mockPluginInstance = new Mock(mockGeneratorContext.Object) { }; + + _mockPlugin?.SetValue(null, mockPluginInstance.Object); + } + + [TearDown] + public void Teardown() + { + _mockPlugin?.SetValue(null, null); + } + + [Test] + public void TestBuildImplements() + { + // mock the model type provider + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var mockModelTypeProvider = new ModelTypeProvider(inputModel, null); + var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider); + var interfaces = jsonMrwSerializationTypeProvider.Implements; + + Assert.IsNotNull(interfaces); + Assert.AreEqual(1, interfaces.Count); + + var expectedJsonModelTInterface = new CSharpType(typeof(IJsonModel<>), mockModelTypeProvider.Type); + + Assert.That(interfaces.Any(i => i.Equals(expectedJsonModelTInterface))); + } + + // This test validates the json model serialization write method is built correctly + [Test] + public void TestBuildJsonModelWriteMethod() + { + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var mockModelTypeProvider = new ModelTypeProvider(inputModel, null); + var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider); + var method = jsonMrwSerializationTypeProvider.BuildJsonModelWriteMethod(); + + Assert.IsNotNull(method); + + var expectedJsonModelInterface = new CSharpType(typeof(IJsonModel<>), mockModelTypeProvider.Type); + var methodSignature = method?.Signature as MethodSignature; + Assert.IsNotNull(methodSignature); + Assert.AreEqual("Write", methodSignature?.Name); + Assert.AreEqual(expectedJsonModelInterface, methodSignature?.ExplicitInterface); + Assert.AreEqual(2, methodSignature?.Parameters.Count); + Assert.IsNull(methodSignature?.ReturnType); + } + + // This test validates the json model deserialization create method is built correctly + [Test] + public void TestBuildJsonModelCreateMethod() + { + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var mockModelTypeProvider = new ModelTypeProvider(inputModel, null); + var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider); + var method = jsonMrwSerializationTypeProvider.BuildJsonModelCreateMethod(); + + Assert.IsNotNull(method); + + var expectedJsonInterface = new CSharpType(typeof(IJsonModel<>), mockModelTypeProvider.Type); + var methodSignature = method?.Signature as MethodSignature; + Assert.IsNotNull(methodSignature); + Assert.AreEqual("Create", methodSignature?.Name); + Assert.AreEqual(expectedJsonInterface, methodSignature?.ExplicitInterface); + Assert.AreEqual(2, methodSignature?.Parameters.Count); + var expectedReturnType = expectedJsonInterface.Arguments[0]; + Assert.AreEqual(expectedReturnType, methodSignature?.ReturnType); + } + + // This test validates the I model serialization write method is built correctly + [Test] + public void TestBuildIModelWriteMethodMethod() + { + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var mockModelTypeProvider = new ModelTypeProvider(inputModel, null); + var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider); + var method = jsonMrwSerializationTypeProvider.BuildIModelWriteMethod(); + + Assert.IsNotNull(method); + + var expectedJsonInterface = new CSharpType(typeof(IPersistableModel), mockModelTypeProvider.Type); + var methodSignature = method?.Signature as MethodSignature; + Assert.IsNotNull(methodSignature); + Assert.AreEqual("Write", methodSignature?.Name); + Assert.AreEqual(expectedJsonInterface, methodSignature?.ExplicitInterface); + Assert.AreEqual(1, methodSignature?.Parameters.Count); + var expectedReturnType = new CSharpType(typeof(BinaryData)); + Assert.AreEqual(expectedReturnType, methodSignature?.ReturnType); + } + + // This test validates the I model deserialization create method is built correctly + [Test] + public void TestBuildIModelDeserializationMethod() + { + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var mockModelTypeProvider = new ModelTypeProvider(inputModel, null); + var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider); + var method = jsonMrwSerializationTypeProvider.BuildIModelCreateMethod(); + + Assert.IsNotNull(method); + + var expectedJsonInterface = new CSharpType(typeof(IPersistableModel), mockModelTypeProvider.Type); + var methodSignature = method?.Signature as MethodSignature; + Assert.IsNotNull(methodSignature); + Assert.AreEqual("Create", methodSignature?.Name); + Assert.AreEqual(expectedJsonInterface, methodSignature?.ExplicitInterface); + Assert.AreEqual(2, methodSignature?.Parameters.Count); + var expectedReturnType = expectedJsonInterface.Arguments[0]; + Assert.AreEqual(expectedReturnType, methodSignature?.ReturnType); + } + + // This test validates the I model get format method is built correctly + [Test] + public void TestBuildIModelGetFormatMethod() + { + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var mockModelTypeProvider = new ModelTypeProvider(inputModel, null); + var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider); + var method = jsonMrwSerializationTypeProvider.BuildIModelGetFormatFromOptionsMethod(); + + Assert.IsNotNull(method); + + var expectedJsonInterface = new CSharpType(typeof(IPersistableModel), mockModelTypeProvider.Type); + var methodSignature = method?.Signature as MethodSignature; + Assert.IsNotNull(methodSignature); + Assert.AreEqual("GetFormatFromOptions", methodSignature?.Name); + Assert.AreEqual(expectedJsonInterface, methodSignature?.ExplicitInterface); + Assert.AreEqual(1, methodSignature?.Parameters.Count); + var expectedReturnType = new CSharpType(typeof(string)); + Assert.AreEqual(expectedReturnType, methodSignature?.ReturnType); + + var methodBody = method?.BodyExpression; + Assert.IsNotNull(methodBody); + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/mocks/Configuration.json b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/mocks/Configuration.json new file mode 100644 index 0000000000..f34eb20cbc --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/mocks/Configuration.json @@ -0,0 +1,8 @@ +{ + "output-folder": "./outputFolder", + "project-folder": "./projectFolder", + "namespace": "sample.namespace", + "unknown-bool-property": false, + "library-name": "sample-library", + "unknown-string-property": "unknownPropertyValue" +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputLibrary.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputLibrary.cs index 90809497b3..2aeebaf5e3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputLibrary.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputLibrary.cs @@ -1,9 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.IO; using System; -using System.Threading.Tasks; +using System.IO; namespace Microsoft.Generator.CSharp.Input { @@ -11,12 +10,15 @@ public class InputLibrary { private const string CodeModelInputFileName = "tspCodeModel.json"; + private readonly string _codeModelPath; + public InputLibrary(string codeModelPath) { - InputNamespace = Load(codeModelPath); + _codeModelPath = codeModelPath; } - public InputNamespace InputNamespace { get; } + private InputNamespace? _inputNamespace; + public InputNamespace InputNamespace => _inputNamespace ??= Load(_codeModelPath); public InputNamespace Load(string outputDirectory) { diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs index aac235e2db..2230a5da25 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Concurrent; @@ -130,28 +130,28 @@ private static InputExampleValue BuildEnumExampleValue(InputEnumType enumType) private static InputExampleValue BuildPrimitiveExampleValue(InputPrimitiveType primitiveType, string? hint) => primitiveType.Kind switch { - InputTypeKind.Stream => InputExampleValue.Stream(primitiveType, ""), - InputTypeKind.Boolean => InputExampleValue.Value(primitiveType, true), - InputTypeKind.Date => InputExampleValue.Value(primitiveType, "2022-05-10"), - InputTypeKind.DateTime => InputExampleValue.Value(primitiveType, "2022-05-10T14:57:31.2311892-04:00"), - InputTypeKind.DateTimeISO8601 => InputExampleValue.Value(primitiveType, "2022-05-10T18:57:31.2311892Z"), - InputTypeKind.DateTimeRFC1123 => InputExampleValue.Value(primitiveType, "Tue, 10 May 2022 18:57:31 GMT"), - InputTypeKind.DateTimeRFC3339 => InputExampleValue.Value(primitiveType, "2022-05-10T18:57:31.2311892Z"), - InputTypeKind.DateTimeRFC7231 => InputExampleValue.Value(primitiveType, "Tue, 10 May 2022 18:57:31 GMT"), - InputTypeKind.DateTimeUnix => InputExampleValue.Value(primitiveType, 1652209051), - InputTypeKind.Float32 => InputExampleValue.Value(primitiveType, 123.45f), - InputTypeKind.Float64 => InputExampleValue.Value(primitiveType, 123.45d), - InputTypeKind.Float128 => InputExampleValue.Value(primitiveType, 123.45m), - InputTypeKind.Guid => InputExampleValue.Value(primitiveType, "73f411fe-4f43-4b4b-9cbd-6828d8f4cf9a"), - InputTypeKind.Int32 => InputExampleValue.Value(primitiveType, 1234), - InputTypeKind.Int64 => InputExampleValue.Value(primitiveType, 1234L), - InputTypeKind.String => string.IsNullOrWhiteSpace(hint) ? InputExampleValue.Value(primitiveType, "") : InputExampleValue.Value(primitiveType, $"<{hint}>"), - InputTypeKind.DurationISO8601 => InputExampleValue.Value(primitiveType, "PT1H23M45S"), - InputTypeKind.DurationConstant => InputExampleValue.Value(primitiveType, "01:23:45"), - InputTypeKind.Time => InputExampleValue.Value(primitiveType, "01:23:45"), - InputTypeKind.Uri => InputExampleValue.Value(primitiveType, "http://localhost:3000"), - InputTypeKind.DurationSeconds => InputExampleValue.Value(primitiveType, 10), - InputTypeKind.DurationSecondsFloat => InputExampleValue.Value(primitiveType, 10f), + InputPrimitiveTypeKind.Stream => InputExampleValue.Stream(primitiveType, ""), + InputPrimitiveTypeKind.Boolean => InputExampleValue.Value(primitiveType, true), + InputPrimitiveTypeKind.Date => InputExampleValue.Value(primitiveType, "2022-05-10"), + InputPrimitiveTypeKind.DateTime => InputExampleValue.Value(primitiveType, "2022-05-10T14:57:31.2311892-04:00"), + InputPrimitiveTypeKind.DateTimeISO8601 => InputExampleValue.Value(primitiveType, "2022-05-10T18:57:31.2311892Z"), + InputPrimitiveTypeKind.DateTimeRFC1123 => InputExampleValue.Value(primitiveType, "Tue, 10 May 2022 18:57:31 GMT"), + InputPrimitiveTypeKind.DateTimeRFC3339 => InputExampleValue.Value(primitiveType, "2022-05-10T18:57:31.2311892Z"), + InputPrimitiveTypeKind.DateTimeRFC7231 => InputExampleValue.Value(primitiveType, "Tue, 10 May 2022 18:57:31 GMT"), + InputPrimitiveTypeKind.DateTimeUnix => InputExampleValue.Value(primitiveType, 1652209051), + InputPrimitiveTypeKind.Float32 => InputExampleValue.Value(primitiveType, 123.45f), + InputPrimitiveTypeKind.Float64 => InputExampleValue.Value(primitiveType, 123.45d), + InputPrimitiveTypeKind.Float128 => InputExampleValue.Value(primitiveType, 123.45m), + InputPrimitiveTypeKind.Guid => InputExampleValue.Value(primitiveType, "73f411fe-4f43-4b4b-9cbd-6828d8f4cf9a"), + InputPrimitiveTypeKind.Int32 => InputExampleValue.Value(primitiveType, 1234), + InputPrimitiveTypeKind.Int64 => InputExampleValue.Value(primitiveType, 1234L), + InputPrimitiveTypeKind.String => string.IsNullOrWhiteSpace(hint) ? InputExampleValue.Value(primitiveType, "") : InputExampleValue.Value(primitiveType, $"<{hint}>"), + InputPrimitiveTypeKind.DurationISO8601 => InputExampleValue.Value(primitiveType, "PT1H23M45S"), + InputPrimitiveTypeKind.DurationConstant => InputExampleValue.Value(primitiveType, "01:23:45"), + InputPrimitiveTypeKind.Time => InputExampleValue.Value(primitiveType, "01:23:45"), + InputPrimitiveTypeKind.Uri => InputExampleValue.Value(primitiveType, "http://localhost:3000"), + InputPrimitiveTypeKind.DurationSeconds => InputExampleValue.Value(primitiveType, 10), + InputPrimitiveTypeKind.DurationSecondsFloat => InputExampleValue.Value(primitiveType, 10f), _ => InputExampleValue.Object(primitiveType, new Dictionary()) }; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputApiKeyAuth.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputApiKeyAuth.cs index 2cafe9dfae..05841cafd9 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputApiKeyAuth.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputApiKeyAuth.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputAuth.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputAuth.cs index 8173f581cf..51055a7c13 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputAuth.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputAuth.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClient.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClient.cs index a7cbef82c5..9af48ace7f 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClient.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClient.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -23,12 +23,12 @@ public InputClient(string name, string description, IReadOnlyList(), true, Array.Empty(), null) { } - public string Name { get; init; } - public string Description { get; init; } - public IReadOnlyList Operations { get; init; } - public bool Creatable { get; init; } - public IReadOnlyList Parameters { get; init; } - public string? Parent { get; init; } + public string Name { get; internal set; } + public string Description { get; internal set; } + public IReadOnlyList Operations { get; internal set; } + public bool Creatable { get; internal set; } + public IReadOnlyList Parameters { get; internal set; } + public string? Parent { get; internal set; } public string Key { diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClientExample.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClientExample.cs index f8e533daab..a6f9624f2b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClientExample.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputClientExample.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; @@ -13,7 +13,7 @@ public InputClientExample(InputClient client, IReadOnlyList ClientParameters { get; } + public InputClient Client { get; init; } + public IReadOnlyList ClientParameters { get; init; } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputConstant.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputConstant.cs index ecb07f2383..be0d71222e 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputConstant.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputConstant.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputDictionary.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputDictionary.cs index c9fed82843..c372911573 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputDictionary.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputDictionary.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumType.cs index 373adbe0f5..544aefaad1 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumType.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumTypeValue.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumTypeValue.cs index 9a89d36733..20864f29ce 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumTypeValue.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputEnumTypeValue.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input @@ -17,6 +17,6 @@ public InputEnumTypeValue(string name, object value, string? description) public string? Description { get; } public virtual string GetJsonValueString() => GetValueString(); - public string GetValueString() => (Value.ToString() ?? string.Empty); + public string GetValueString() => Value.ToString() ?? string.Empty; } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleListValue.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleListValue.cs index b0be8db6ef..1afb5a5aaa 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleListValue.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleListValue.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleObjectValue.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleObjectValue.cs index dc8bcbb3f9..363b08e776 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleObjectValue.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleObjectValue.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleRawValue.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleRawValue.cs index 53bfe88ed6..5f734b7638 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleRawValue.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleRawValue.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleStreamValue.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleStreamValue.cs index 68c525d1b7..2fde54e2d6 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleStreamValue.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleStreamValue.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleValue.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleValue.cs index 079debf493..244388303a 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleValue.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputExampleValue.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputGenericType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputGenericType.cs index a842c891d3..d93b5308fc 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputGenericType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputGenericType.cs @@ -1,19 +1,20 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; +using System.Collections.Generic; namespace Microsoft.Generator.CSharp.Input { public class InputGenericType : InputType { - public InputGenericType(Type type, InputType argumentType, bool isNullable) : base(type.Name, isNullable) + public InputGenericType(Type type, IReadOnlyList arguments, bool isNullable) : base(type.Name, isNullable) { Type = type; - ArgumentType = argumentType; + Arguments = arguments; } public Type Type { get; } - public InputType ArgumentType { get; } + public IReadOnlyList Arguments { get; } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputIntrinsicType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputIntrinsicType.cs index e56f40cf7f..13a80088c7 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputIntrinsicType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputIntrinsicType.cs @@ -1,8 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input { + // TODO -- after we have adopted getAllModels in our emitter, we no longer need to have this type. https://github.com/microsoft/typespec/issues/3338 + // The only thing we need in these "intrinsic types" is the "unknown", and TCGC put it in the primitive type. Others we will never generate therefore we do not need to have others public class InputIntrinsicType : InputType { public InputIntrinsicType(InputIntrinsicTypeKind kind) : base(kind.ToString(), false) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputList.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputList.cs index ad10b96043..5873470b36 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputList.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputList.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputLiteralType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputLiteralType.cs index 89b895dd55..9c59a8a63b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputLiteralType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputLiteralType.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelProperty.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelProperty.cs index f827c3490a..c09ba02c91 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelProperty.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelProperty.cs @@ -1,8 +1,6 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; - namespace Microsoft.Generator.CSharp.Input { public class InputModelProperty diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs index 7eacebd015..e96de832c0 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs @@ -1,12 +1,12 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.CompilerServices; namespace Microsoft.Generator.CSharp.Input { + [DebuggerDisplay("{GetDebuggerDisplay(),nq}")] public class InputModelType : InputType { public InputModelType(string name, string? modelNamespace, string? accessibility, string? deprecated, string? description, InputModelTypeUsage usage, IReadOnlyList properties, InputModelType? baseModel, IReadOnlyList derivedModels, string? discriminatorValue, string? discriminatorPropertyName, InputDictionary? inheritedDictionaryType, bool isNullable) @@ -27,27 +27,20 @@ public InputModelType(string name, string? modelNamespace, string? accessibility IsPropertyBag = false; } - public string? Namespace { get; } - public string? Accessibility { get; } - public string? Deprecated { get; } - public string? Description { get; } - public InputModelTypeUsage Usage { get; } - public IReadOnlyList Properties { get; } - public InputModelType? BaseModel { get; private set; } - public IReadOnlyList DerivedModels { get; } - public string? DiscriminatorValue { get; } - public string? DiscriminatorPropertyName { get; } - public InputDictionary? InheritedDictionaryType { get; } + public string? Namespace { get; internal set; } + public string? Accessibility { get; internal set; } + public string? Deprecated { get; internal set; } + public string? Description { get; internal set; } + public InputModelTypeUsage Usage { get; internal set; } + public IReadOnlyList Properties { get; internal set; } + public InputModelType? BaseModel { get; internal set; } + public IReadOnlyList DerivedModels { get; internal set; } + public string? DiscriminatorValue { get; internal set; } + public string? DiscriminatorPropertyName { get; internal set; } + public InputDictionary? InheritedDictionaryType { get; internal set; } public bool IsUnknownDiscriminatorModel { get; init; } public bool IsPropertyBag { get; init; } - internal void SetBaseModel(InputModelType? baseModel, [CallerFilePath] string filepath = "", [CallerMemberName] string caller = "") - { - Debug.Assert(filepath.EndsWith($"{nameof(TypeSpecInputModelTypeConverter)}.cs"), $"This method is only allowed to be called in `TypeSpecInputModelTypeConverter.cs`"); - Debug.Assert(caller == nameof(TypeSpecInputModelTypeConverter.CreateModelType), $"This method is only allowed to be called in `TypeSpecInputModelTypeConverter.CreateModelType`"); - BaseModel = baseModel; - } - public IEnumerable GetSelfAndBaseModels() => EnumerateBase(this); public IEnumerable GetAllBaseModels() => EnumerateBase(BaseModel); @@ -72,30 +65,9 @@ private static IEnumerable EnumerateBase(InputModelType? model) } } - public bool Equals(InputType other, bool handleCollections) - { - if (!handleCollections) - return Equals(other); - - switch (other) - { - case InputDictionary otherDictionary: - return Equals(otherDictionary.ValueType); - case InputList otherList: - return Equals(otherList.ElementType); - default: - return Equals(other); - } - } - - internal InputModelProperty? GetProperty(InputModelType key) + private string GetDebuggerDisplay() { - foreach (var property in Properties) - { - if (key.Equals(property.Type, true)) - return property; - } - return null; + return $"Model (Name: {Name}, {Namespace})"; } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelTypeUsage.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelTypeUsage.cs index e6724cf344..7ae2397736 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelTypeUsage.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelTypeUsage.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -11,6 +11,7 @@ public enum InputModelTypeUsage None = 0, Input = 1, Output = 2, - RoundTrip = Input | Output + Json = 4, + RoundTrip = Input | Output, } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputNamespace.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputNamespace.cs index 4d32b0c56a..5f442ce46c 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputNamespace.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputNamespace.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOAuth2Auth.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOAuth2Auth.cs index f49b21cd69..a00121271e 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOAuth2Auth.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOAuth2Auth.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperation.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperation.cs index 980e8040d6..95c06f1f18 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperation.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperation.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -75,25 +75,25 @@ public InputOperation() : this( generateConvenienceMethod: false) { } - public string Name { get; init; } - public string? ResourceName { get; init; } - public string? Summary { get; init; } - public string? Deprecated { get; init; } - public string Description { get; init; } - public string? Accessibility { get; init; } - public IReadOnlyList Parameters { get; init; } - public IReadOnlyList Responses { get; init; } - public string HttpMethod { get; init; } - public BodyMediaType RequestBodyMediaType { get; init; } - public string Uri { get; init; } - public string Path { get; init; } - public string? ExternalDocsUrl { get; init; } - public IReadOnlyList? RequestMediaTypes { get; init; } - public bool BufferResponse { get; init; } - public OperationLongRunning? LongRunning { get; init; } - public OperationPaging? Paging { get; init; } - public bool GenerateProtocolMethod { get; init; } - public bool GenerateConvenienceMethod { get; init; } + public string Name { get; internal set; } + public string? ResourceName { get; internal set; } + public string? Summary { get; internal set; } + public string? Deprecated { get; internal set; } + public string Description { get; internal set; } + public string? Accessibility { get; internal set; } + public IReadOnlyList Parameters { get; internal set; } + public IReadOnlyList Responses { get; internal set; } + public string HttpMethod { get; internal set; } + public BodyMediaType RequestBodyMediaType { get; internal set; } + public string Uri { get; internal set; } + public string Path { get; internal set; } + public string? ExternalDocsUrl { get; internal set; } + public IReadOnlyList? RequestMediaTypes { get; internal set; } + public bool BufferResponse { get; internal set; } + public OperationLongRunning? LongRunning { get; internal set; } + public OperationPaging? Paging { get; internal set; } + public bool GenerateProtocolMethod { get; internal set; } + public bool GenerateConvenienceMethod { get; internal set; } private IReadOnlyDictionary? _examples; internal IReadOnlyDictionary Examples => _examples ??= EnsureExamples(); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperationExample.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperationExample.cs index cc0b17c81c..122fd4a35f 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperationExample.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputOperationExample.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameter.cs index fb891ee772..9e7d48c6ea 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameterExample.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameterExample.cs index d8dc38b1c3..22853681ff 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameterExample.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputParameterExample.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputPrimitiveType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputPrimitiveType.cs index d4b875f849..fbf0df66e3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputPrimitiveType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputPrimitiveType.cs @@ -1,48 +1,48 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input { public sealed class InputPrimitiveType : InputType { - public InputPrimitiveType(InputTypeKind kind, bool isNullable = false) : base(kind.ToString(), isNullable) + public InputPrimitiveType(InputPrimitiveTypeKind kind, bool isNullable = false) : base(kind.ToString(), isNullable) { Kind = kind; } - public InputTypeKind Kind { get; } + public InputPrimitiveTypeKind Kind { get; } - public static InputPrimitiveType BinaryData { get; } = new(InputTypeKind.BinaryData); - public static InputPrimitiveType Boolean { get; } = new(InputTypeKind.Boolean); - public static InputPrimitiveType Bytes { get; } = new(InputTypeKind.Bytes); - public static InputPrimitiveType BytesBase64Url { get; } = new(InputTypeKind.BytesBase64Url); - public static InputPrimitiveType ContentType { get; } = new(InputTypeKind.ContentType); - public static InputPrimitiveType Date { get; } = new(InputTypeKind.Date); - public static InputPrimitiveType DateTime { get; } = new(InputTypeKind.DateTime); - public static InputPrimitiveType DateTimeISO8601 { get; } = new(InputTypeKind.DateTimeISO8601); - public static InputPrimitiveType DateTimeRFC1123 { get; } = new(InputTypeKind.DateTimeRFC1123); - public static InputPrimitiveType DateTimeRFC3339 { get; } = new(InputTypeKind.DateTimeRFC3339); - public static InputPrimitiveType DateTimeRFC7231 { get; } = new(InputTypeKind.DateTimeRFC7231); - public static InputPrimitiveType DateTimeUnix { get; } = new(InputTypeKind.DateTimeUnix); - public static InputPrimitiveType DurationISO8601 { get; } = new(InputTypeKind.DurationISO8601); - public static InputPrimitiveType DurationConstant { get; } = new(InputTypeKind.DurationConstant); - public static InputPrimitiveType ETag { get; } = new(InputTypeKind.ETag); - public static InputPrimitiveType Float32 { get; } = new(InputTypeKind.Float32); - public static InputPrimitiveType Float64 { get; } = new(InputTypeKind.Float64); - public static InputPrimitiveType Float128 { get; } = new(InputTypeKind.Float128); - public static InputPrimitiveType Guid { get; } = new(InputTypeKind.Guid); - public static InputPrimitiveType Int32 { get; } = new(InputTypeKind.Int32); - public static InputPrimitiveType Int64 { get; } = new(InputTypeKind.Int64); - public static InputPrimitiveType IPAddress { get; } = new(InputTypeKind.IPAddress); - public static InputPrimitiveType Object { get; } = new(InputTypeKind.Object); - public static InputPrimitiveType RequestMethod { get; } = new(InputTypeKind.RequestMethod); - public static InputPrimitiveType ResourceIdentifier { get; } = new(InputTypeKind.ResourceIdentifier); - public static InputPrimitiveType ResourceType { get; } = new(InputTypeKind.ResourceType); - public static InputPrimitiveType Stream { get; } = new(InputTypeKind.Stream); - public static InputPrimitiveType String { get; } = new(InputTypeKind.String); - public static InputPrimitiveType Time { get; } = new(InputTypeKind.Time); - public static InputPrimitiveType Uri { get; } = new(InputTypeKind.Uri); + public static InputPrimitiveType BinaryData { get; } = new(InputPrimitiveTypeKind.BinaryData); + public static InputPrimitiveType Boolean { get; } = new(InputPrimitiveTypeKind.Boolean); + public static InputPrimitiveType Bytes { get; } = new(InputPrimitiveTypeKind.Bytes); + public static InputPrimitiveType BytesBase64Url { get; } = new(InputPrimitiveTypeKind.BytesBase64Url); + public static InputPrimitiveType ContentType { get; } = new(InputPrimitiveTypeKind.ContentType); + public static InputPrimitiveType Date { get; } = new(InputPrimitiveTypeKind.Date); + public static InputPrimitiveType DateTime { get; } = new(InputPrimitiveTypeKind.DateTime); + public static InputPrimitiveType DateTimeISO8601 { get; } = new(InputPrimitiveTypeKind.DateTimeISO8601); + public static InputPrimitiveType DateTimeRFC1123 { get; } = new(InputPrimitiveTypeKind.DateTimeRFC1123); + public static InputPrimitiveType DateTimeRFC3339 { get; } = new(InputPrimitiveTypeKind.DateTimeRFC3339); + public static InputPrimitiveType DateTimeRFC7231 { get; } = new(InputPrimitiveTypeKind.DateTimeRFC7231); + public static InputPrimitiveType DateTimeUnix { get; } = new(InputPrimitiveTypeKind.DateTimeUnix); + public static InputPrimitiveType DurationISO8601 { get; } = new(InputPrimitiveTypeKind.DurationISO8601); + public static InputPrimitiveType DurationConstant { get; } = new(InputPrimitiveTypeKind.DurationConstant); + public static InputPrimitiveType ETag { get; } = new(InputPrimitiveTypeKind.ETag); + public static InputPrimitiveType Float32 { get; } = new(InputPrimitiveTypeKind.Float32); + public static InputPrimitiveType Float64 { get; } = new(InputPrimitiveTypeKind.Float64); + public static InputPrimitiveType Float128 { get; } = new(InputPrimitiveTypeKind.Float128); + public static InputPrimitiveType Guid { get; } = new(InputPrimitiveTypeKind.Guid); + public static InputPrimitiveType Int32 { get; } = new(InputPrimitiveTypeKind.Int32); + public static InputPrimitiveType Int64 { get; } = new(InputPrimitiveTypeKind.Int64); + public static InputPrimitiveType IPAddress { get; } = new(InputPrimitiveTypeKind.IPAddress); + public static InputPrimitiveType Object { get; } = new(InputPrimitiveTypeKind.Object); + public static InputPrimitiveType RequestMethod { get; } = new(InputPrimitiveTypeKind.RequestMethod); + public static InputPrimitiveType ResourceIdentifier { get; } = new(InputPrimitiveTypeKind.ResourceIdentifier); + public static InputPrimitiveType ResourceType { get; } = new(InputPrimitiveTypeKind.ResourceType); + public static InputPrimitiveType Stream { get; } = new(InputPrimitiveTypeKind.Stream); + public static InputPrimitiveType String { get; } = new(InputPrimitiveTypeKind.String); + public static InputPrimitiveType Time { get; } = new(InputPrimitiveTypeKind.Time); + public static InputPrimitiveType Uri { get; } = new(InputPrimitiveTypeKind.Uri); - public bool IsNumber => Kind is InputTypeKind.Int32 or InputTypeKind.Int64 or InputTypeKind.Float32 or InputTypeKind.Float64 or InputTypeKind.Float128; + public bool IsNumber => Kind is InputPrimitiveTypeKind.Int32 or InputPrimitiveTypeKind.Int64 or InputPrimitiveTypeKind.Float32 or InputPrimitiveTypeKind.Float64 or InputPrimitiveTypeKind.Float128; } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputTypeKind.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputPrimitiveTypeKind.cs similarity index 89% rename from packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputTypeKind.cs rename to packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputPrimitiveTypeKind.cs index 6c25fdcda9..ad8a219bce 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputTypeKind.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputPrimitiveTypeKind.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input { - public enum InputTypeKind + public enum InputPrimitiveTypeKind { Boolean, BinaryData, diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputType.cs index c5545e9b47..49738286a3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputType.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input @@ -6,18 +6,21 @@ namespace Microsoft.Generator.CSharp.Input /// /// Represents an input type to the generator. /// - /// The name of the input type. - /// Flag to determine if the type is nullable. public abstract class InputType { + /// + /// Construct a new instance + /// + /// The name of the input type. + /// Flag to determine if the type is nullable. protected InputType(string name, bool isNullable) { Name = name; IsNullable = isNullable; } - public string Name { get; } - public bool IsNullable { get; } + public string Name { get; internal set; } + public bool IsNullable { get; internal set; } internal InputType GetCollectionEquivalent(InputType inputType) { diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputUnionType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputUnionType.cs index 8d480f6d52..4f27f894c5 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputUnionType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputUnionType.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationLongRunning.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationLongRunning.cs index c43497dc62..be16ce45d7 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationLongRunning.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationLongRunning.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Linq; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationPaging.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationPaging.cs index 4d47549f36..75b6fe5339 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationPaging.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationPaging.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponse.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponse.cs index 091638cc8b..00b4618207 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponse.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponseHeader.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponseHeader.cs index 3851f632ae..a5dd8d4a77 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponseHeader.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/OperationResponseHeader.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Input diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputClientConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputClientConverter.cs new file mode 100644 index 0000000000..535929976f --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputClientConverter.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.Generator.CSharp.Input +{ + internal sealed class TypeSpecInputClientConverter : JsonConverter + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public TypeSpecInputClientConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputClient? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.ReadReferenceAndResolve(_referenceHandler.CurrentResolver) ?? CreateInputClient(ref reader, null, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputClient value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + private static InputClient? CreateInputClient(ref Utf8JsonReader reader, string? id, JsonSerializerOptions options, ReferenceResolver resolver) + { + if (id == null) + { + reader.TryReadReferenceId(ref id); + } + id = id ?? throw new JsonException(); + + var client = new InputClient(); + resolver.AddReference(id, client); + + string? name = null; + string? description = null; + IReadOnlyList? operations = null; + bool creatable = false; + IReadOnlyList? parameters = null; + string? parent = null; + + while (reader.TokenType != JsonTokenType.EndObject) + { + var isKnownProperty = reader.TryReadString(nameof(InputClient.Name), ref name) + || reader.TryReadString(nameof(InputClient.Description), ref description) + || reader.TryReadWithConverter(nameof(InputClient.Operations), options, ref operations) + || reader.TryReadBoolean(nameof(InputClient.Creatable), ref creatable) + || reader.TryReadWithConverter(nameof(InputClient.Parameters), options, ref parameters) + || reader.TryReadString(nameof(InputClient.Parent), ref parent); + + if (!isKnownProperty) + { + reader.SkipProperty(); + } + } + + client.Name = name ?? throw new JsonException("InputClient must have name"); + client.Description = description ?? throw new JsonException("InputClient must have description"); + client.Operations = operations ?? Array.Empty(); + client.Creatable = creatable; + client.Parameters = parameters ?? Array.Empty(); + client.Parent = parent; + + return client; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputConstantConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputConstantConverter.cs index c07305bb24..cf48a0cd13 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputConstantConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputConstantConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -68,38 +68,37 @@ public static object ReadConstantValue(ref Utf8JsonReader reader, string propert case InputPrimitiveType primitiveType: switch (primitiveType.Kind) { - case InputTypeKind.String: + case InputPrimitiveTypeKind.String: value = reader.GetString() ?? throw new JsonException(); break; - case InputTypeKind.Uri: + case InputPrimitiveTypeKind.Uri: var stringvalue = reader.GetString() ?? throw new JsonException(); value = new Uri(stringvalue); break; - case InputTypeKind.Int32: + case InputPrimitiveTypeKind.Int32: value = reader.GetInt32(); break; - case InputTypeKind.Int64: + case InputPrimitiveTypeKind.Int64: value = reader.GetInt64(); break; - case InputTypeKind.Boolean: + case InputPrimitiveTypeKind.Boolean: value = reader.GetBoolean(); break; default: value = reader.GetString() ?? throw new JsonException(); break; - } break; case InputEnumType enumType: switch (enumType.EnumValueType.Kind) { - case InputTypeKind.String: + case InputPrimitiveTypeKind.String: value = reader.GetString() ?? throw new JsonException(); break; - case InputTypeKind.Int32: + case InputPrimitiveTypeKind.Int32: value = reader.GetInt32(); break; - case InputTypeKind.Float32: + case InputPrimitiveTypeKind.Float32: value = reader.GetDouble(); break; default: diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeConverter.cs index 9d4f6ee8b8..b69f0a78ba 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeConverter.cs @@ -114,19 +114,19 @@ private static IReadOnlyList NormalizeValues(IReadOnlyList reader.GetString() ?? throw new JsonException(), - InputTypeKind.Int32 => reader.GetInt32(), - InputTypeKind.Float32 => reader.GetSingle(), - InputTypeKind.Float64 => reader.GetDouble(), - InputTypeKind.Boolean => reader.GetBoolean(), + InputPrimitiveTypeKind.String => reader.GetString() ?? throw new JsonException(), + InputPrimitiveTypeKind.Int32 => reader.GetInt32(), + InputPrimitiveTypeKind.Float32 => reader.GetSingle(), + InputPrimitiveTypeKind.Float64 => reader.GetDouble(), + InputPrimitiveTypeKind.Boolean => reader.GetBoolean(), _ => throw new JsonException($"Not supported literal type {kind}.") }; reader.Read(); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs index 0b84a69c1f..1e0b8c31d1 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -18,18 +18,35 @@ public TypeSpecInputModelTypeConverter(TypeSpecReferenceHandler referenceHandler } public override InputModelType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - => ReadModelType(ref reader, options, _referenceHandler.CurrentResolver); + => reader.ReadReferenceAndResolve(_referenceHandler.CurrentResolver) ?? CreateModelType(ref reader, null, null, options, _referenceHandler.CurrentResolver); public override void Write(Utf8JsonWriter writer, InputModelType value, JsonSerializerOptions options) => throw new NotSupportedException("Writing not supported"); - private static InputModelType? ReadModelType(ref Utf8JsonReader reader, JsonSerializerOptions options, ReferenceResolver resolver) - => reader.ReadReferenceAndResolve(resolver) ?? CreateModelType(ref reader, null, null, options, resolver); - public static InputModelType CreateModelType(ref Utf8JsonReader reader, string? id, string? name, JsonSerializerOptions options, ReferenceResolver resolver) { - var isFirstProperty = id == null && name == null; - var properties = new List(); + if (id == null) + { + reader.TryReadReferenceId(ref id); + } + + id = id ?? throw new JsonException(); + + // skip every other property until we have a name + while (name == null) + { + var hasName = reader.TryReadString(nameof(InputModelType.Name), ref name); + if (!hasName) + { + reader.SkipProperty(); + } + } + name = name ?? throw new JsonException("Model must have name"); + + // create an empty model to resolve circular references + var model = new InputModelType(name, null, null, null, null, InputModelTypeUsage.None, null!, null, new List(), null, null, null, false); + resolver.AddReference(id, model); + bool isNullable = false; string? ns = null; string? accessibility = null; @@ -40,12 +57,12 @@ public static InputModelType CreateModelType(ref Utf8JsonReader reader, string? string? discriminatorValue = null; InputDictionary? inheritedDictionaryType = null; InputModelType? baseModel = null; - InputModelType? model = null; + IReadOnlyList? properties = null; + + // read all possible properties and throw away the unknown properties while (reader.TokenType != JsonTokenType.EndObject) { - var isKnownProperty = reader.TryReadReferenceId(ref isFirstProperty, ref id) - || reader.TryReadString(nameof(InputModelType.Name), ref name) - || reader.TryReadBoolean(nameof(InputModelType.IsNullable), ref isNullable) + var isKnownProperty = reader.TryReadBoolean(nameof(InputModelType.IsNullable), ref isNullable) || reader.TryReadString(nameof(InputModelType.Namespace), ref ns) || reader.TryReadString(nameof(InputModelType.Accessibility), ref accessibility) || reader.TryReadString(nameof(InputModelType.Deprecated), ref deprecated) @@ -53,88 +70,33 @@ public static InputModelType CreateModelType(ref Utf8JsonReader reader, string? || reader.TryReadString(nameof(InputModelType.Usage), ref usageString) || reader.TryReadString(nameof(InputModelType.DiscriminatorPropertyName), ref discriminatorPropertyName) || reader.TryReadString(nameof(InputModelType.DiscriminatorValue), ref discriminatorValue) - || reader.TryReadWithConverter(nameof(InputModelType.InheritedDictionaryType), options, ref inheritedDictionaryType); + || reader.TryReadWithConverter(nameof(InputModelType.InheritedDictionaryType), options, ref inheritedDictionaryType) + || reader.TryReadWithConverter(nameof(InputModelType.BaseModel), options, ref baseModel) + || reader.TryReadWithConverter(nameof(InputModelType.Properties), options, ref properties); - if (isKnownProperty) - { - continue; - } - /** - * If the model has base model, `BaseModel` and `Properties` should be the last two items in tspCodeModel. - * and `BaseModel` should be last but one, and `Properties` should be the last one. - */ - if (reader.GetString() == nameof(InputModelType.BaseModel)) - { - model = CreateInputModelTypeInstance(id, name, ns, accessibility, deprecated, description, usageString, discriminatorValue, discriminatorPropertyName, baseModel, properties, inheritedDictionaryType, isNullable, resolver); - reader.TryReadWithConverter(nameof(InputModelType.BaseModel), options, ref baseModel); - if (baseModel != null) - { - model.SetBaseModel(baseModel); - var baseModelDerived = (List)resolver.ResolveReference($"{baseModel.Name}.{nameof(InputModelType.DerivedModels)}"); - baseModelDerived.Add(model); - } - continue; - } - if (reader.GetString() == nameof(InputModelType.Properties)) - { - model = model ?? CreateInputModelTypeInstance(id, name, ns, accessibility, deprecated, description, usageString, discriminatorValue, discriminatorPropertyName, baseModel, properties, inheritedDictionaryType, isNullable, resolver); - reader.Read(); - CreateProperties(ref reader, properties, options); - if (reader.TokenType != JsonTokenType.EndObject) - { - throw new JsonException($"{nameof(InputModelType)}.{nameof(InputModelType.Properties)} must be the last defined property for id '{id}', name '{name}'."); - } - } - else + if (!isKnownProperty) { reader.SkipProperty(); } } - return model ?? CreateInputModelTypeInstance(id, name, ns, accessibility, deprecated, description, usageString, discriminatorValue, discriminatorPropertyName, baseModel, properties, inheritedDictionaryType, isNullable, resolver); - } - - private static InputModelType CreateInputModelTypeInstance(string? id, string? name, string? ns, string? accessibility, string? deprecated, string? description, string? usageString, string? discriminatorValue, string? discriminatorPropertyValue, InputModelType? baseModel, IReadOnlyList properties, InputDictionary? inheritedDictionaryType, bool isNullable, ReferenceResolver resolver) - { - name = name ?? throw new JsonException("Model must have name"); - InputModelTypeUsage usage = InputModelTypeUsage.None; - if (usageString != null) - { - Enum.TryParse(usageString, ignoreCase: true, out usage); - } - - var derivedModels = new List(); - var model = new InputModelType(name, ns, accessibility, deprecated, description, usage, properties, baseModel, derivedModels, discriminatorValue, discriminatorPropertyValue, inheritedDictionaryType, isNullable: isNullable); - - if (id is not null) - { - resolver.AddReference(id, model); - resolver.AddReference($"{model.Name}.{nameof(InputModelType.DerivedModels)}", derivedModels); - } - - if (baseModel is not null) - { - var baseModelDerived = (List)resolver.ResolveReference($"{baseModel.Name}.{nameof(InputModelType.DerivedModels)}"); - baseModelDerived.Add(model); - } + model.Name = name ?? throw new JsonException("InputModelType must have name"); + model.Namespace = ns; + model.Accessibility = accessibility; + model.Deprecated = deprecated; + model.Description = description; + var parsedUsage = Enum.TryParse(usageString, ignoreCase: true, out var usage) ? usage : InputModelTypeUsage.None; + // TO-DO: Manually add JSON usage flag for now until support for parsing this is added to the TSP https://github.com/microsoft/typespec/issues/3392 + parsedUsage |= InputModelTypeUsage.Json; + model.Usage = parsedUsage; + model.DiscriminatorValue = discriminatorValue; + model.DiscriminatorPropertyName = discriminatorPropertyName; + model.InheritedDictionaryType = inheritedDictionaryType; + model.IsNullable = isNullable; + model.BaseModel = baseModel; + model.Properties = properties ?? Array.Empty(); return model; } - - private static void CreateProperties(ref Utf8JsonReader reader, ICollection properties, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.StartArray) - { - throw new JsonException(); - } - reader.Read(); - - while (reader.TokenType != JsonTokenType.EndArray) - { - var property = reader.ReadWithConverter(options); - properties.Add(property ?? throw new JsonException($"null {nameof(InputModelProperty)} is not allowed")); - } - reader.Read(); - } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs new file mode 100644 index 0000000000..5a24626fb7 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.Generator.CSharp.Input +{ + internal sealed class TypeSpecInputNamespaceConverter : JsonConverter + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public TypeSpecInputNamespaceConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputNamespace? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => ReadInputNamespace(ref reader, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputNamespace value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + private static InputNamespace? ReadInputNamespace(ref Utf8JsonReader reader, JsonSerializerOptions options, ReferenceResolver resolver) + { + if (reader.TokenType == JsonTokenType.StartObject) + { + reader.Read(); + } + + string? name = null; + string? description = null; + IReadOnlyList? apiVersions = null; + IReadOnlyList? enums = null; + IReadOnlyList? models = null; + IReadOnlyList? clients = null; + InputAuth? auth = null; + + while (reader.TokenType != JsonTokenType.EndObject) + { + var isKnownProperty = reader.TryReadString(nameof(InputNamespace.Name), ref name) + || reader.TryReadString(nameof(InputNamespace.Description), ref description) + || reader.TryReadWithConverter(nameof(InputNamespace.ApiVersions), options, ref apiVersions) + || reader.TryReadWithConverter(nameof(InputNamespace.Enums), options, ref enums) + || reader.TryReadWithConverter(nameof(InputNamespace.Models), options, ref models) + || reader.TryReadWithConverter(nameof(InputNamespace.Clients), options, ref clients) + || reader.TryReadWithConverter(nameof(InputNamespace.Auth), options, ref auth); + + if (!isKnownProperty) + { + reader.SkipProperty(); + } + } + + apiVersions ??= Array.Empty(); + enums ??= Array.Empty(); + models ??= Array.Empty(); + clients ??= Array.Empty(); + + // resolve the derived models now + foreach (var model in models) + { + if (model.BaseModel is { } baseModel) + { + ((List)baseModel.DerivedModels).Add(model); + } + } + + return new InputNamespace( + name ?? throw new JsonException(), + description ?? throw new JsonException(), + apiVersions, + enums, + models, + clients, + auth ?? throw new JsonException()); + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputOperationConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputOperationConverter.cs new file mode 100644 index 0000000000..e8e7c073c7 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputOperationConverter.cs @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.Generator.CSharp.Input +{ + internal sealed class TypeSpecInputOperationConverter : JsonConverter + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public TypeSpecInputOperationConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputOperation? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.ReadReferenceAndResolve(_referenceHandler.CurrentResolver) ?? CreateInputOperation(ref reader, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputOperation value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + private static InputOperation? CreateInputOperation(ref Utf8JsonReader reader, JsonSerializerOptions options, ReferenceResolver resolver) + { + if (reader.TokenType == JsonTokenType.StartObject) + { + reader.Read(); + } + string? id = null; + reader.TryReadReferenceId(ref id); + id = id ?? throw new JsonException(); + + var operation = new InputOperation(); + resolver.AddReference(id, operation); + + string? name = null; + string? resourceName = null; + string? description = null; + string? summary = null; + string? deprecated = null; + string? accessibility = null; + IReadOnlyList? parameters = null; + IReadOnlyList? responses = null; + string? httpMethod = null; + BodyMediaType requestBodyMediaType = default; + string? uri = null; + string? path = null; + string? externalDocsUrl = null; + IReadOnlyList? requestMediaTypes = null; + bool bufferResponse = false; + OperationLongRunning? longRunning = null; + OperationPaging? paging = null; + bool generateProtocolMethod = false; + bool generateConvenienceMethod = false; + + while (reader.TokenType != JsonTokenType.EndObject) + { + var isKnownProperty = reader.TryReadString(nameof(InputOperation.Name), ref name) + || reader.TryReadString(nameof(InputOperation.ResourceName), ref resourceName) + || reader.TryReadString(nameof(InputOperation.Summary), ref summary) + || reader.TryReadString(nameof(InputOperation.Deprecated), ref deprecated) + || reader.TryReadString(nameof(InputOperation.Description), ref description) + || reader.TryReadString(nameof(InputOperation.Accessibility), ref accessibility) + || reader.TryReadWithConverter(nameof(InputOperation.Parameters), options, ref parameters) + || reader.TryReadWithConverter(nameof(InputOperation.Responses), options, ref responses) + || reader.TryReadString(nameof(InputOperation.HttpMethod), ref httpMethod) + || reader.TryReadWithConverter(nameof(InputOperation.RequestBodyMediaType), options, ref requestBodyMediaType) + || reader.TryReadString(nameof(InputOperation.Uri), ref uri) + || reader.TryReadString(nameof(InputOperation.Path), ref path) + || reader.TryReadString(nameof(InputOperation.ExternalDocsUrl), ref externalDocsUrl) + || reader.TryReadWithConverter(nameof(InputOperation.RequestMediaTypes), options, ref requestMediaTypes) + || reader.TryReadBoolean(nameof(InputOperation.BufferResponse), ref bufferResponse) + || reader.TryReadWithConverter(nameof(InputOperation.LongRunning), options, ref longRunning) + || reader.TryReadWithConverter(nameof(InputOperation.Paging), options, ref paging) + || reader.TryReadBoolean(nameof(InputOperation.GenerateProtocolMethod), ref generateProtocolMethod) + || reader.TryReadBoolean(nameof(InputOperation.GenerateConvenienceMethod), ref generateConvenienceMethod); + + if (!isKnownProperty) + { + reader.SkipProperty(); + } + } + + operation.Name = name ?? throw new JsonException("InputOperation must have name"); + operation.ResourceName = resourceName; + operation.Summary = summary; + operation.Deprecated = deprecated; + operation.Description = description ?? name; // default to name to avoid a case that we do not have description (and leads to no xml doc at all) + operation.Accessibility = accessibility; + operation.Parameters = parameters ?? Array.Empty(); + operation.Responses = responses ?? Array.Empty(); + operation.HttpMethod = httpMethod ?? throw new JsonException("InputOperation must have HttpMethod"); + operation.RequestBodyMediaType = requestBodyMediaType; + operation.Uri = uri ?? throw new JsonException("InputOperation must have Uri"); + operation.Path = path ?? throw new JsonException("InputOperation must have Path"); + operation.ExternalDocsUrl = externalDocsUrl; + operation.RequestMediaTypes = requestMediaTypes; + operation.BufferResponse = bufferResponse; + operation.LongRunning = longRunning; + operation.Paging = paging; + operation.GenerateProtocolMethod = generateProtocolMethod; + operation.GenerateConvenienceMethod = generateConvenienceMethod; + + return operation; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs index 014bcac874..c4f7a8b176 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -105,7 +105,7 @@ public static InputPrimitiveType ReadPrimitiveType(ref Utf8JsonReader reader, st public static InputPrimitiveType CreatePrimitiveType(string? inputTypeKindString, bool isNullable) { ArgumentNullException.ThrowIfNull(inputTypeKindString, nameof(inputTypeKindString)); - return Enum.TryParse(inputTypeKindString, ignoreCase: true, out var kind) + return Enum.TryParse(inputTypeKindString, ignoreCase: true, out var kind) ? new InputPrimitiveType(kind, isNullable) : throw new JsonException($"{inputTypeKindString} type is unknown."); } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecReferenceHandler.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecReferenceHandler.cs index d1b4410c69..2403dd3aea 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecReferenceHandler.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecReferenceHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -34,7 +34,7 @@ public override string GetReference(object value, out bool alreadyExists) => throw new InvalidOperationException("JSON writing isn't supported"); public override object ResolveReference(string referenceId) - => _referenceIdToObjectMap.TryGetValue(referenceId, out object? value) ? value : throw new JsonException(); + => _referenceIdToObjectMap.TryGetValue(referenceId, out object? value) ? value : throw new JsonException($"cannot resolve reference {referenceId}"); } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs index 1f54c81781..7171563dc1 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Text.Json; @@ -14,21 +14,27 @@ public static class TypeSpecSerialization var options = new JsonSerializerOptions { ReferenceHandler = referenceHandler, - AllowTrailingCommas = true + AllowTrailingCommas = true, + Converters = + { + new TypeSpecInputNamespaceConverter(referenceHandler), + new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), + new TypeSpecInputTypeConverter(referenceHandler), + new TypeSpecInputListTypeConverter(referenceHandler), + new TypeSpecInputDictionaryTypeConverter(referenceHandler), + new TypeSpecInputEnumTypeConverter(referenceHandler), + new TypeSpecInputEnumTypeValueConverter(referenceHandler), + new TypeSpecInputModelTypeConverter(referenceHandler), + new TypeSpecInputModelPropertyConverter(referenceHandler), + new TypeSpecInputConstantConverter(referenceHandler), + new TypeSpecInputLiteralTypeConverter(referenceHandler), + new TypeSpecInputUnionTypeConverter(referenceHandler), + new TypeSpecInputClientConverter(referenceHandler), + new TypeSpecInputOperationConverter(referenceHandler), + new TypeSpecInputParameterConverter(referenceHandler) + } }; - options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); - options.Converters.Add(new TypeSpecInputTypeConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputListTypeConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputDictionaryTypeConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputEnumTypeConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputEnumTypeValueConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputModelTypeConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputModelPropertyConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputConstantConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputLiteralTypeConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputUnionTypeConverter(referenceHandler)); - options.Converters.Add(new TypeSpecInputParameterConverter(referenceHandler)); return JsonSerializer.Deserialize(json, options); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/Utf8JsonReaderExtensions.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/Utf8JsonReaderExtensions.cs index 2435f7bb80..1ab03eea8d 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/Utf8JsonReaderExtensions.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/Utf8JsonReaderExtensions.cs @@ -1,7 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; @@ -9,6 +10,24 @@ namespace Microsoft.Generator.CSharp.Input { internal static class Utf8JsonReaderExtensions { + public static bool TryReadReferenceId(this ref Utf8JsonReader reader, ref string? id) + { + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } + + if (reader.GetString() != "$id") + { + return false; + } + + reader.Read(); + id = reader.GetString() ?? throw new JsonException(); + reader.Read(); + return true; + } + public static bool TryReadReferenceId(this ref Utf8JsonReader reader, ref bool isFirstProperty, ref string? value) { if (reader.TokenType != JsonTokenType.PropertyName) @@ -145,6 +164,35 @@ public static bool TryReadWithConverter(this ref Utf8JsonReader reader, strin return true; } + public static bool TryReadWithConverter(this ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref IReadOnlyList? value) + { + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } + + if (reader.GetString() != propertyName) + { + return false; + } + + reader.Read(); + var result = new List(); + if (reader.TokenType != JsonTokenType.StartArray) + { + throw new JsonException(); + } + reader.Read(); + while (reader.TokenType != JsonTokenType.EndArray) + { + var item = reader.ReadWithConverter(options); + result.Add(item ?? throw new JsonException()); + } + reader.Read(); + value = result; + return true; + } + public static T? ReadWithConverter(this ref Utf8JsonReader reader, JsonSerializerOptions options) { var converter = (JsonConverter)options.GetConverter(typeof(T)); @@ -173,7 +221,7 @@ public static bool TryReadWithConverter(this ref Utf8JsonReader reader, strin reader.Read(); var idRef = reader.GetString() ?? throw new JsonException("$ref can't be null"); - var result = (T)resolver.ResolveReference(idRef ?? throw new JsonException()); + var result = (T)resolver.ResolveReference(idRef); reader.Read(); if (reader.TokenType != JsonTokenType.EndObject) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.sln b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.sln index 007aed44bb..481eeeef87 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.sln +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.sln @@ -23,6 +23,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestProjects.Local.Tests", "TestProjects\Local\TestProjects.Local.Tests.csproj", "{BFE39EDA-ADA1-4F60-A47C-ADE88C67B3B7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Generator.CSharp.ClientModel.Tests", "Microsoft.Generator.CSharp.ClientModel\test\Microsoft.Generator.CSharp.ClientModel.Tests.csproj", "{D30EC838-B0A0-44CD-A361-239FF256A176}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,6 +59,10 @@ Global {BFE39EDA-ADA1-4F60-A47C-ADE88C67B3B7}.Debug|Any CPU.Build.0 = Debug|Any CPU {BFE39EDA-ADA1-4F60-A47C-ADE88C67B3B7}.Release|Any CPU.ActiveCfg = Release|Any CPU {BFE39EDA-ADA1-4F60-A47C-ADE88C67B3B7}.Release|Any CPU.Build.0 = Release|Any CPU + {D30EC838-B0A0-44CD-A361-239FF256A176}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D30EC838-B0A0-44CD-A361-239FF256A176}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D30EC838-B0A0-44CD-A361-239FF256A176}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D30EC838-B0A0-44CD-A361-239FF256A176}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CSharpGen.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CSharpGen.cs index 038291ff9d..95cd95c6f1 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CSharpGen.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CSharpGen.cs @@ -36,6 +36,13 @@ public async Task ExecuteAsync() CodeWriter writer = new CodeWriter(); CodeModelPlugin.Instance.GetWriter(writer, model).Write(); generateFilesTasks.Add(workspace.AddGeneratedFile(Path.Combine("src", "Generated", "Models", $"{model.Name}.cs"), writer.ToString())); + + foreach (var serialization in model.SerializationProviders) + { + CodeWriter serializationWriter = new CodeWriter(); + CodeModelPlugin.Instance.GetWriter(serializationWriter, serialization).Write(); + generateFilesTasks.Add(workspace.AddGeneratedFile(Path.Combine("src", "Generated", "Models", $"{serialization.Name}.Serialization.cs"), serializationWriter.ToString())); + } } foreach (var client in output.Clients) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CodeModelPlugin.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CodeModelPlugin.cs index a358d12cd1..b9fa186b25 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CodeModelPlugin.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/CodeModelPlugin.cs @@ -2,10 +2,10 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; using System.ComponentModel.Composition; using Microsoft.Generator.CSharp.Expressions; using Microsoft.Generator.CSharp.Input; -using Microsoft.Generator.CSharp.Writers; namespace Microsoft.Generator.CSharp { @@ -38,5 +38,11 @@ public CodeModelPlugin(GeneratorContext context) public abstract OutputLibrary OutputLibrary { get; } public InputLibrary InputLibrary => _inputLibrary.Value; public virtual TypeProviderWriter GetWriter(CodeWriter writer, TypeProvider provider) => new(writer, provider); + + /// + /// Returns a serialization type provider for the given model type provider. + /// + /// The model type provider. + public abstract IReadOnlyList GetSerializationTypeProviders(ModelTypeProvider provider); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Configuration.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Configuration.cs index d4758553f3..38cfd97c18 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Configuration.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Configuration.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -114,7 +114,7 @@ internal static Configuration Load(string outputPath, string? json = null) : JsonDocument.Parse(json).RootElement; return new Configuration( - outputPath.Equals(string.Empty) ? outputPath :Path.GetFullPath(outputPath), + outputPath.Equals(string.Empty) ? outputPath : Path.GetFullPath(outputPath), ParseAdditionalConfigOptions(root), ReadOption(root, Options.ClearOutputFolder), ReadOption(root, Options.GenerateModelFactory), diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/IntExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/IntExpression.cs index 6b8d62e329..433fed93c2 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/IntExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/IntExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Expressions @@ -6,5 +6,16 @@ namespace Microsoft.Generator.CSharp.Expressions public sealed record IntExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) { public static IntExpression MaxValue => new(StaticProperty(nameof(int.MaxValue))); + public IntExpression Add(IntExpression value) => Operator("+", value); + public IntExpression Minus(IntExpression value) => Operator("-", value); + public IntExpression Multiply(IntExpression value) => Operator("*", value); + public IntExpression DivideBy(IntExpression value) => Operator("/", value); + + public static IntExpression operator +(IntExpression left, IntExpression right) => left.Add(right); + public static IntExpression operator -(IntExpression left, IntExpression right) => left.Minus(right); + public static IntExpression operator *(IntExpression left, IntExpression right) => left.Multiply(right); + public static IntExpression operator /(IntExpression left, IntExpression right) => left.DivideBy(right); + + private IntExpression Operator(string op, IntExpression other) => new(new BinaryOperatorExpression(op, this, other)); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonDocumentExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonDocumentExpression.cs index b46f0157e9..51c4e67f0d 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonDocumentExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonDocumentExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Text.Json; @@ -18,7 +18,7 @@ public static JsonDocumentExpression Parse(StreamExpression stream, bool async) { // Sync and async methods have different set of parameters return async - ? new JsonDocumentExpression(InvokeStatic(nameof(JsonDocument.ParseAsync), new[] { stream, Snippets.Default, KnownParameters.CancellationTokenParameter }, true)) + ? new JsonDocumentExpression(InvokeStatic(nameof(JsonDocument.ParseAsync), new[] { stream, Snippets.Default, Snippets.Default }, true)) : new JsonDocumentExpression(InvokeStatic(nameof(JsonDocument.Parse), stream)); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonElementExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonElementExpression.cs index 5b402c0d48..cef7c3e4ca 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonElementExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonElementExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Text.Json; @@ -18,9 +18,6 @@ public sealed record JsonElementExpression(ValueExpression Untyped) : TypedValue public ValueExpression GetArrayLength() => Invoke(nameof(JsonElement.GetArrayLength)); public ValueExpression GetBoolean() => Invoke(nameof(JsonElement.GetBoolean)); public ValueExpression GetBytesFromBase64() => Invoke(nameof(JsonElement.GetBytesFromBase64)); - public ValueExpression GetBytesFromBase64(string? format) => Extensible.JsonElement.GetBytesFromBase64(this, format); - public ValueExpression GetChar() => Extensible.JsonElement.GetChar(this); - public ValueExpression GetDateTimeOffset(string? format) => Extensible.JsonElement.GetDateTimeOffset(this, format); public ValueExpression GetDateTime() => Invoke(nameof(JsonElement.GetDateTime)); public ValueExpression GetDecimal() => Invoke(nameof(JsonElement.GetDecimal)); public ValueExpression GetDouble() => Invoke(nameof(JsonElement.GetDouble)); @@ -30,11 +27,9 @@ public sealed record JsonElementExpression(ValueExpression Untyped) : TypedValue public ValueExpression GetInt16() => Invoke(nameof(JsonElement.GetInt16)); public ValueExpression GetInt32() => Invoke(nameof(JsonElement.GetInt32)); public ValueExpression GetInt64() => Invoke(nameof(JsonElement.GetInt64)); - public ValueExpression GetObject() => Extensible.JsonElement.GetObject(this); public StringExpression GetRawText() => new(Invoke(nameof(JsonElement.GetRawText))); public ValueExpression GetSingle() => Untyped.Invoke(nameof(JsonElement.GetSingle)); public StringExpression GetString() => new(Untyped.Invoke(nameof(JsonElement.GetString))); - public ValueExpression GetTimeSpan(string? format) => Extensible.JsonElement.GetTimeSpan(this, format); public BoolExpression ValueKindEqualsNull() => new(new BinaryOperatorExpression("==", Property(nameof(JsonElement.ValueKind)), FrameworkEnumValue(JsonValueKind.Null))); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonPropertyExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonPropertyExpression.cs index 609aeb92dd..fa5d9c080b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonPropertyExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/JsonPropertyExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Text.Json; @@ -12,7 +12,5 @@ public sealed record JsonPropertyExpression(ValueExpression Untyped) : TypedValu public JsonElementExpression Value => new(Property(nameof(JsonProperty.Value))); public BoolExpression NameEquals(string value) => new(Invoke(nameof(JsonProperty.NameEquals), LiteralU8(value))); - - public MethodBodyStatement ThrowNonNullablePropertyIsNull() => Extensible.JsonElement.ThrowNonNullablePropertyIsNull(this); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StreamExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StreamExpression.cs index 885d7ffc85..3aae8e83a2 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StreamExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StreamExpression.cs @@ -1,14 +1,16 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.IO; namespace Microsoft.Generator.CSharp.Expressions { public sealed record StreamExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) { - internal MethodBodyStatement CopyTo(StreamExpression destination) => new InvokeInstanceMethodStatement(Untyped, nameof(Stream.CopyTo), destination); + public MethodBodyStatement CopyTo(StreamExpression destination) => new InvokeInstanceMethodStatement(Untyped, nameof(Stream.CopyTo), destination); - internal ValueExpression Position => new TypedMemberExpression(this, nameof(Stream.Position), typeof(long)); + public ValueExpression Position => new TypedMemberExpression(this, nameof(Stream.Position), typeof(long)); + public ValueExpression GetBuffer => new InvokeInstanceMethodExpression(this, nameof(MemoryStream.GetBuffer), Array.Empty(), null, false); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringBuilderExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringBuilderExpression.cs index b8dec661bb..f4b0774f48 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringBuilderExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringBuilderExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Text; @@ -7,7 +7,7 @@ namespace Microsoft.Generator.CSharp.Expressions { public sealed record StringBuilderExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) { - public StringExpression Length => new(Property(nameof(StringBuilder.Length))); + public IntExpression Length => new(Property(nameof(StringBuilder.Length))); public MethodBodyStatement Append(StringExpression value) => new InvokeInstanceMethodStatement(Untyped, nameof(StringBuilder.Append), value); @@ -24,5 +24,7 @@ public sealed record StringBuilderExpression(ValueExpression Untyped) : TypedVal public MethodBodyStatement Append(FormattableStringExpression value) => new InvokeInstanceMethodStatement(Untyped, nameof(StringBuilder.Append), value); public MethodBodyStatement AppendLine(FormattableStringExpression value) => new InvokeInstanceMethodStatement(Untyped, nameof(StringBuilder.AppendLine), value); + + public MethodBodyStatement Remove(ValueExpression startIndex, ValueExpression length) => new InvokeInstanceMethodStatement(Untyped, nameof(StringBuilder.Remove), startIndex, length); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringExpression.cs index 3d51ed4c91..53359e378d 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/StringExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -26,5 +26,7 @@ public static StringExpression Join(ValueExpression separator, ValueExpression v public StringExpression Substring(ValueExpression startIndex) => new(new InvokeInstanceMethodExpression(this, nameof(string.Substring), new[] { startIndex }, null, false)); + public ValueExpression ToCharArray() + => new InvokeInstanceMethodExpression(this, nameof(string.ToCharArray), Array.Empty(), null, false); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/Utf8JsonWriterExpression.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/Utf8JsonWriterExpression.cs index b6766e5bf2..9471439d76 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/Utf8JsonWriterExpression.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Expressions/Utf8JsonWriterExpression.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -23,9 +23,6 @@ public sealed record Utf8JsonWriterExpression(ValueExpression Untyped) : TypedVa public MethodBodyStatement WriteNull(ValueExpression propertyName) => new InvokeInstanceMethodStatement(Untyped, nameof(Utf8JsonWriter.WriteNull), propertyName); public MethodBodyStatement WriteNullValue() => new InvokeInstanceMethodStatement(Untyped, nameof(Utf8JsonWriter.WriteNullValue)); - public MethodBodyStatement WriteObjectValue(ValueExpression value) - => new InvokeStaticMethodStatement(CodeModelPlugin.Instance.Configuration.ApiTypes.Utf8JsonWriterExtensionsType, CodeModelPlugin.Instance.Configuration.ApiTypes.Utf8JsonWriterExtensionsWriteObjectValueName, new[] { Untyped, value }, null, true); - public MethodBodyStatement WriteNumberValue(ValueExpression value) => new InvokeInstanceMethodStatement(Untyped, nameof(Utf8JsonWriter.WriteNumberValue), value); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ApiTypes.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ApiTypes.cs index 67a616b910..95c08a0eed 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ApiTypes.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ApiTypes.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -12,15 +12,6 @@ namespace Microsoft.Generator.CSharp /// public abstract class ApiTypes { - /// - /// The type for change tracking lists. - /// - public abstract Type ChangeTrackingListType { get; } - /// - /// The type for change tracking dictionaries. - /// - public abstract Type ChangeTrackingDictionaryType { get; } - /// /// The sample value for the endpoint. /// @@ -44,7 +35,6 @@ public Type GetValueTaskOfResponse(Type? valueType = default) => valueType is null ? typeof(ValueTask<>).MakeGenericType(ResponseType) : typeof(ValueTask<>).MakeGenericType(ResponseOfTType.MakeGenericType(valueType)); public abstract Type HttpPipelineType { get; } - public abstract Type PipelineExtensionsType { get; } public abstract string HttpPipelineCreateMessageName { get; } public FormattableString GetHttpPipelineCreateMessageFormat(bool withContext) { @@ -58,9 +48,6 @@ public FormattableString GetHttpPipelineCreateMessageFormat(bool withContext) public Type GetNextPageFuncType() => typeof(Func<,,>).MakeGenericType(typeof(int?), typeof(string), HttpMessageType); - public abstract Type ClientDiagnosticsType { get; } - public abstract string ClientDiagnosticsCreateScopeName { get; } - public abstract Type ClientOptionsType { get; } public abstract Type RequestContextType { get; } @@ -73,7 +60,7 @@ public FormattableString GetHttpPipelineCreateMessageFormat(bool withContext) public abstract FormattableString GetHttpPipelineBearerString(string pipelineField, string optionsVariable, string credentialVariable, string scopesParamName); public FormattableString GetHttpPipelineKeyCredentialString(string pipelineField, string optionsVariable, string credentialVariable, string keyName) => $"{pipelineField} = {HttpPipelineBuilderType}.Build({optionsVariable}, new {KeyCredentialPolicyType}({credentialVariable}, \"{keyName}\"));"; - public abstract FormattableString GetHttpPipelineClassifierString(string pipelineField, string optionsVariable, FormattableString perCallPolicies, FormattableString perRetryPolicies); + public abstract FormattableString GetHttpPipelineClassifierString(string pipelineField, string optionsVariable, FormattableString perCallPolicies, FormattableString perRetryPolicies, FormattableString beforeTransportPolicies); public abstract Type HttpPipelinePolicyType { get; } public abstract string HttpMessageRequestName { get; } @@ -85,29 +72,11 @@ public FormattableString GetHttpPipelineKeyCredentialString(string pipelineField // public abstract Action WriteHeaderMethod { get; } public abstract FormattableString GetSetContentString(string requestName, string contentName); - public abstract Type RequestUriType { get; } public abstract Type RequestContentType { get; } public abstract string ToRequestContentName { get; } public abstract string RequestContentCreateName { get; } - public abstract Type IUtf8JsonSerializableType { get; } public abstract Type IXmlSerializableType { get; } - public abstract string IUtf8JsonSerializableWriteName { get; } - - public abstract Type Utf8JsonWriterExtensionsType { get; } - public abstract string Utf8JsonWriterExtensionsWriteObjectValueName { get; } - public abstract string Utf8JsonWriterExtensionsWriteNumberValueName { get; } - public abstract string Utf8JsonWriterExtensionsWriteStringValueName { get; } - public abstract string Utf8JsonWriterExtensionsWriteBase64StringValueName { get; } - - public abstract Type OptionalType { get; } - public abstract Type OptionalPropertyType { get; } - - public abstract string OptionalIsCollectionDefinedName { get; } - public abstract string OptionalIsDefinedName { get; } - public abstract string OptionalToDictionaryName { get; } - public abstract string OptionalToListName { get; } - public abstract string OptionalToNullableName { get; } public abstract Type RequestFailedExceptionType { get; } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethod.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethod.cs index 59e809a2f9..df7cceb084 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethod.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethod.cs @@ -15,19 +15,33 @@ public sealed class CSharpMethod /// public CSharpMethodKinds Kind { get; } public MethodSignatureBase Signature { get; } - public MethodBodyStatement? Body { get; } + public MethodBodyStatement? BodyStatements { get; } + public ValueExpression? BodyExpression { get; } /// /// Initializes a new instance of the class with a body statement and method signature. /// /// The method signature. - /// The method body. + /// The method body. /// The method kind . - public CSharpMethod(MethodSignatureBase signature, MethodBodyStatement body, CSharpMethodKinds kind) + public CSharpMethod(MethodSignatureBase signature, MethodBodyStatement bodyStatements, CSharpMethodKinds? kind = null) { Signature = signature; - Body = body; - Kind = kind; + BodyStatements = bodyStatements; + Kind = kind ?? new CSharpMethodKinds("Undefined"); + } + + /// + /// Initializes a new instance of the class with a body expression and method signature. + /// + /// The method signature. + /// The method body expression. + /// The method kind . + public CSharpMethod(MethodSignatureBase signature, ValueExpression bodyExpression, CSharpMethodKinds? kind = null) + { + Signature = signature; + BodyExpression = bodyExpression; + Kind = kind ?? new CSharpMethodKinds("Undefined"); } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethodKinds.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethodKinds.cs index ebf0f3f12d..1d3645ca36 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethodKinds.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethodKinds.cs @@ -19,7 +19,7 @@ namespace Microsoft.Generator.CSharp private readonly string _value; - /// Initializes a new instance of the structure. + /// Initializes a new instance of the structure. /// The string value of the instance. /// is null. public CSharpMethodKinds(string value) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs index c650423adf..0aa884c7be 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ExpressionPropertyBody.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using Microsoft.Generator.CSharp.Expressions; -namespace Microsoft.Generator.CSharp.Models +namespace Microsoft.Generator.CSharp { internal record ExpressionPropertyBody(ValueExpression Getter) : PropertyBody; } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/KnownParameters.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/KnownParameters.cs index 090e16fe0c..07df1adbf4 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/KnownParameters.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/KnownParameters.cs @@ -28,7 +28,6 @@ public KnownParameters(TypeFactory typeFactory) public Parameter MatchConditionsParameter => new("matchConditions", $"The content to send as the request conditions of the request.", TypeFactory.MatchConditionsType(), Snippets.DefaultOf(TypeFactory.RequestConditionsType()), ValidationType.None, null, RequestLocation: RequestLocation.Header); public Parameter RequestConditionsParameter => new("requestConditions", $"The content to send as the request conditions of the request.", TypeFactory.RequestConditionsType(), Snippets.DefaultOf(TypeFactory.RequestConditionsType()), ValidationType.None, null, RequestLocation: RequestLocation.Header); - public static readonly Parameter ClientDiagnostics = new("clientDiagnostics", $"The handler for diagnostic messaging in the client.", new CSharpType(CodeModelPlugin.Instance.Configuration.ApiTypes.ClientDiagnosticsType), null, ValidationType.AssertNotNull, null); public static readonly Parameter Pipeline = new("pipeline", $"The HTTP pipeline for sending and receiving REST requests and responses", new CSharpType(CodeModelPlugin.Instance.Configuration.ApiTypes.HttpPipelineType), null, ValidationType.AssertNotNull, null); public static readonly Parameter KeyAuth = new("keyCredential", $"The key credential to copy", new CSharpType(CodeModelPlugin.Instance.Configuration.ApiTypes.KeyCredentialType), null, ValidationType.None, null); public static readonly Parameter Endpoint = new("endpoint", $"Service endpoint", new CSharpType(typeof(Uri)), null, ValidationType.None, null, RequestLocation: RequestLocation.Uri, IsEndpoint: true); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/MethodPropertyBody.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/MethodPropertyBody.cs index f8784e1612..aae45abf46 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/MethodPropertyBody.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/MethodPropertyBody.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using Microsoft.Generator.CSharp.Expressions; -namespace Microsoft.Generator.CSharp.Models +namespace Microsoft.Generator.CSharp { internal record MethodPropertyBody(MethodBodyStatement Getter, MethodBodyStatement? Setter = null, MethodSignatureModifiers SetterModifiers = MethodSignatureModifiers.None) : PropertyBody; } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ModelTypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ModelTypeProvider.cs index 8a9d479d84..5c3660a55b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ModelTypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/ModelTypeProvider.cs @@ -13,14 +13,18 @@ namespace Microsoft.Generator.CSharp public sealed class ModelTypeProvider : TypeProvider { private readonly InputModelType _inputModel; - public override string Name { get; } + /// + /// The serializations providers for the model provider. + /// + public IReadOnlyList SerializationProviders { get; } = Array.Empty(); + public ModelTypeProvider(InputModelType inputModel, SourceInputModel? sourceInputModel) : base(sourceInputModel) { + _inputModel = inputModel; Name = inputModel.Name.ToCleanName(); - if (inputModel.Accessibility == "internal") { DeclarationModifiers = TypeSignatureModifiers.Partial | TypeSignatureModifiers.Internal; @@ -32,7 +36,10 @@ public ModelTypeProvider(InputModelType inputModel, SourceInputModel? sourceInpu DeclarationModifiers |= TypeSignatureModifiers.Abstract; } - _inputModel = inputModel; + if (inputModel.Usage.HasFlag(InputModelTypeUsage.Json)) + { + SerializationProviders = CodeModelPlugin.Instance.GetSerializationTypeProviders(this); + } } protected override PropertyDeclaration[] BuildProperties() @@ -240,7 +247,7 @@ private static ValidationType GetParameterValidation(InputModelProperty property null, accessibility, constructorParameters), - body: new MethodBodyStatement[] + bodyStatements: new MethodBodyStatement[] { new ParameterValidationBlock(constructorParameters), GetPropertyInitializers(constructorParameters) @@ -261,7 +268,7 @@ private CSharpMethod BuildSerializationConstructor() null, MethodSignatureModifiers.Internal, constructorParameters), - body: new MethodBodyStatement[] + bodyStatements: new MethodBodyStatement[] { new ParameterValidationBlock(constructorParameters), GetPropertyInitializers(constructorParameters) @@ -314,7 +321,7 @@ private CSharpMethod BuildEmptyConstructor() var accessibility = IsStruct ? MethodSignatureModifiers.Public : MethodSignatureModifiers.Internal; return new CSharpMethod( signature: new ConstructorSignature(Type, $"Initializes a new instance of {Type:C} for deserialization.", null, accessibility, Array.Empty()), - body: new MethodBodyStatement(), + bodyStatements: new MethodBodyStatement(), kind: CSharpMethodKinds.Constructor); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/TypeFactory.cs index 4ee668af0b..29df093f8e 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/TypeFactory.cs @@ -42,20 +42,20 @@ public abstract class TypeFactory InputDictionary dictionaryType => GetSerializationFormat(dictionaryType.ValueType), InputPrimitiveType primitiveType => primitiveType.Kind switch { - InputTypeKind.BytesBase64Url => SerializationFormat.Bytes_Base64Url, - InputTypeKind.Bytes => SerializationFormat.Bytes_Base64, - InputTypeKind.Date => SerializationFormat.Date_ISO8601, - InputTypeKind.DateTime => SerializationFormat.DateTime_ISO8601, - InputTypeKind.DateTimeISO8601 => SerializationFormat.DateTime_ISO8601, - InputTypeKind.DateTimeRFC1123 => SerializationFormat.DateTime_RFC1123, - InputTypeKind.DateTimeRFC3339 => SerializationFormat.DateTime_RFC3339, - InputTypeKind.DateTimeRFC7231 => SerializationFormat.DateTime_RFC7231, - InputTypeKind.DateTimeUnix => SerializationFormat.DateTime_Unix, - InputTypeKind.DurationISO8601 => SerializationFormat.Duration_ISO8601, - InputTypeKind.DurationConstant => SerializationFormat.Duration_Constant, - InputTypeKind.DurationSeconds => SerializationFormat.Duration_Seconds, - InputTypeKind.DurationSecondsFloat => SerializationFormat.Duration_Seconds_Float, - InputTypeKind.Time => SerializationFormat.Time_ISO8601, + InputPrimitiveTypeKind.BytesBase64Url => SerializationFormat.Bytes_Base64Url, + InputPrimitiveTypeKind.Bytes => SerializationFormat.Bytes_Base64, + InputPrimitiveTypeKind.Date => SerializationFormat.Date_ISO8601, + InputPrimitiveTypeKind.DateTime => SerializationFormat.DateTime_ISO8601, + InputPrimitiveTypeKind.DateTimeISO8601 => SerializationFormat.DateTime_ISO8601, + InputPrimitiveTypeKind.DateTimeRFC1123 => SerializationFormat.DateTime_RFC1123, + InputPrimitiveTypeKind.DateTimeRFC3339 => SerializationFormat.DateTime_RFC3339, + InputPrimitiveTypeKind.DateTimeRFC7231 => SerializationFormat.DateTime_RFC7231, + InputPrimitiveTypeKind.DateTimeUnix => SerializationFormat.DateTime_Unix, + InputPrimitiveTypeKind.DurationISO8601 => SerializationFormat.Duration_ISO8601, + InputPrimitiveTypeKind.DurationConstant => SerializationFormat.Duration_Constant, + InputPrimitiveTypeKind.DurationSeconds => SerializationFormat.Duration_Seconds, + InputPrimitiveTypeKind.DurationSecondsFloat => SerializationFormat.Duration_Seconds_Float, + InputPrimitiveTypeKind.Time => SerializationFormat.Time_ISO8601, _ => SerializationFormat.Default }, _ => SerializationFormat.Default diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.ModelSnippets.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.ModelSnippets.cs index 3f70547645..b11691f8b5 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.ModelSnippets.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.ModelSnippets.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. namespace Microsoft.Generator.CSharp.Expressions @@ -7,9 +7,7 @@ public abstract partial class ExtensibleSnippets { public abstract class ModelSnippets { - public abstract CSharpMethod BuildConversionToRequestBodyMethod(MethodSignatureModifiers modifiers); public abstract CSharpMethod BuildFromOperationResponseMethod(TypeProvider typeProvider, MethodSignatureModifiers modifiers); - public abstract TypedValueExpression InvokeToRequestBodyMethod(TypedValueExpression model); } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.RestOperationsSnippets.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.RestOperationsSnippets.cs index 4a061486b7..bda468145f 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.RestOperationsSnippets.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.RestOperationsSnippets.cs @@ -9,8 +9,6 @@ public abstract partial class ExtensibleSnippets { public abstract class RestOperationsSnippets { - public abstract TypedValueExpression InvokeServiceOperationCall(TypedValueExpression pipeline, TypedValueExpression message, bool async); - public abstract TypedValueExpression GetTypedResponseFromValue(TypedValueExpression value, TypedValueExpression response); public abstract TypedValueExpression GetTypedResponseFromModel(TypeProvider typeProvider, TypedValueExpression response); public abstract TypedValueExpression GetTypedResponseFromEnum(EnumType enumType, TypedValueExpression response); @@ -18,7 +16,6 @@ public abstract class RestOperationsSnippets public abstract MethodBodyStatement DeclareHttpMessage(MethodSignatureBase createRequestMethodSignature, out TypedValueExpression message); public abstract MethodBodyStatement DeclareContentWithUtf8JsonWriter(out TypedValueExpression content, out Utf8JsonWriterExpression writer); - public abstract MethodBodyStatement InvokeServiceOperationCallAndReturnHeadAsBool(TypedValueExpression pipeline, TypedValueExpression message, TypedValueExpression clientDiagnostics, bool async); public abstract StreamExpression GetContentStream(TypedValueExpression response); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.cs index fc60785295..af31598a6b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Snippets/ExtensibleSnippets.cs @@ -5,7 +5,6 @@ namespace Microsoft.Generator.CSharp.Expressions { public abstract partial class ExtensibleSnippets { - public abstract JsonElementSnippets JsonElement { get; } public abstract ModelSnippets Model { get; } public abstract RestOperationsSnippets RestOperations { get; } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/SourceInput/ClientSourceInput.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/SourceInput/ClientSourceInput.cs index 93750e5342..f81e9360d2 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/SourceInput/ClientSourceInput.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/SourceInput/ClientSourceInput.cs @@ -3,7 +3,7 @@ using Microsoft.CodeAnalysis; -namespace Microsoft.Generator.CSharp.Input +namespace Microsoft.Generator.CSharp { internal record ClientSourceInput(INamedTypeSymbol? ParentClientType); } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriter.Documentation.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriter.Documentation.cs new file mode 100644 index 0000000000..e1fb0db576 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriter.Documentation.cs @@ -0,0 +1,281 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Microsoft.Generator.CSharp +{ + public sealed partial class CodeWriter + { + public CodeWriter WriteXmlDocumentationSummary(FormattableString? text) + { + return WriteXmlDocumentation("summary", text); + } + + public CodeWriter WriteXmlDocumentation(string tag, FormattableString? text) + { + return WriteDocumentationLines($"<{tag}>", $"", text); + } + + public CodeWriter WriteXmlDocumentationParameters(IEnumerable parameters) + { + foreach (var parameter in parameters) + { + WriteXmlDocumentationParameter(parameter); + } + + return this; + } + + public CodeWriter WriteXmlDocumentationParameter(string name, FormattableString? text) + { + return WriteDocumentationLines($"", $"", text); + } + + /// + /// Writes XML documentation for a parameter of a method using a "param" tag. + /// + /// Writer to which code is written to. + /// The definition of the parameter, including name and description. + /// + public CodeWriter WriteXmlDocumentationParameter(Parameter parameter) + { + return WriteXmlDocumentationParameter(parameter.Name, parameter.Description); + } + + public CodeWriter WriteXmlDocumentationException(CSharpType exception, FormattableString? description) + { + return WriteDocumentationLines($"", $"", description); + } + + public CodeWriter WriteXmlDocumentationReturns(FormattableString text) + { + return WriteDocumentationLines($"", $"", text); + } + + public CodeWriter WriteXmlDocumentationInclude(string filename, MethodSignature methodSignature, out string memberId) + { + // We use short names of types for external doc reference member id + // This is not good enough for cref, but for now works as member id + // Change to cref-style names if needed + var sb = new StringBuilder(); + sb.Append(methodSignature.Name).Append("("); + foreach (var parameter in methodSignature.Parameters) + { + AppendTypeWithShortNames(parameter.Type, sb); + sb.Append(","); + } + + sb.Remove(sb.Length - 1, 1); + sb.Append(")"); + + memberId = sb.ToString(); + return WriteRawLine($"/// "); + } + + private static void AppendTypeWithShortNames(CSharpType type, StringBuilder sb) + { + sb.Append(type.TryGetCSharpFriendlyName(out var keywordName) ? keywordName : type.Name); + + if (type.Arguments.Any()) + { + sb.Append("{"); + foreach (var typeArgument in type.Arguments) + { + AppendTypeWithShortNames(typeArgument, sb); + sb.Append(","); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("}"); + } + + if (type is { IsNullable: true, IsValueType: true }) + { + sb.Append("?"); + } + } + + public CodeWriter WriteXmlDocumentationRequiredParametersException(IEnumerable parameters) + { + return WriteXmlDocumentationParametersExceptions(typeof(ArgumentNullException), parameters.Where(p => p.Validation is ValidationType.AssertNotNull or ValidationType.AssertNotNullOrEmpty).ToArray(), " is null."); + } + + public CodeWriter WriteXmlDocumentationNonEmptyParametersException(IEnumerable parameters) + { + return WriteXmlDocumentationParametersExceptions(typeof(ArgumentException), parameters.Where(p => p.Validation == ValidationType.AssertNotNullOrEmpty).ToArray(), " is an empty string, and was expected to be non-empty."); + } + + private CodeWriter WriteXmlDocumentationParametersExceptions(Type exceptionType, IReadOnlyCollection parameters, string reason) + { + if (parameters.Count == 0) + { + return this; + } + + var formatBuilder = new StringBuilder(); + for (var i = 0; i < parameters.Count - 2; ++i) + { + formatBuilder.Append(", "); + } + + if (parameters.Count > 1) + { + formatBuilder.Append(" or "); + } + + formatBuilder.Append(""); + formatBuilder.Append(reason); + + var description = FormattableStringFactory.Create(formatBuilder.ToString(), parameters.Select(p => (object)p.Name).ToArray()); + return WriteXmlDocumentationException(exceptionType, description); + } + + public CodeWriter WriteDocumentationLines(FormattableString startTag, FormattableString endTag, FormattableString? text) + => AppendXmlDocumentation(startTag, endTag, text ?? $""); + + public CodeWriter WriteMethodDocumentation(MethodSignatureBase methodBase) + { + if (methodBase.IsRawSummaryText) + { + return WriteRawXmlDocumentation(methodBase.Description); + } + + if (methodBase.NonDocumentComment is { } comment) + { + WriteLine($"// {comment}"); + } + + if (methodBase.SummaryText is { } summaryText) + { + WriteXmlDocumentationSummary(summaryText); + } + + return WriteMethodDocumentationSignature(methodBase); + } + + public CodeWriter WriteMethodDocumentationSignature(MethodSignatureBase methodBase) + { + WriteXmlDocumentationParameters(methodBase.Modifiers.HasFlag(MethodSignatureModifiers.Public) ? methodBase.Parameters : methodBase.Parameters.Where(p => p.Description is not null)); + + WriteXmlDocumentationRequiredParametersException(methodBase.Parameters); + WriteXmlDocumentationNonEmptyParametersException(methodBase.Parameters); + if (methodBase is MethodSignature { ReturnDescription: { } } method) + { + WriteXmlDocumentationReturns(method.ReturnDescription); + } + + return this; + } + + public CodeWriter WriteXmlDocumentationInheritDoc(CSharpType? crefType = null) + => crefType == null + ? WriteLine($"/// ") + : WriteLine($"/// "); + + internal CodeWriter WriteRawXmlDocumentation(FormattableString? content) + { + if (content is null) + return this; + + var lines = content.ToString().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); + var xmlLines = string.Join('\n', lines.Select(l => "/// " + l)); + AppendRaw(xmlLines); + WriteLine(); + return this; + } + + internal CodeWriter AppendXmlDocumentation(FormattableString startTag, FormattableString endTag, FormattableString content) + { + const string xmlDoc = "/// "; + const string xmlDocNewLine = "\n/// "; + + var commentStart = _length; + AppendRaw(CurrentLine.IsEmpty ? xmlDoc : xmlDocNewLine); + + var startTagStart = _length; + Append(startTag); + _writingXmlDocumentation = true; + + var contentStart = _length; + if (content.Format.Length > 0) + { + Append(content); + } + var contentEnd = _length; + + _writingXmlDocumentation = false; + Append(endTag); + + if (contentStart == contentEnd) + { + var startTagSpan = WrittenText.Slice(startTagStart + 1, contentStart - startTagStart - 1); + var endTagSpan = WrittenText.Slice(contentEnd + 2); + + if (startTagSpan.SequenceEqual(endTagSpan)) + { + // Remove empty tags + _length = commentStart; + } + else + { + WriteLine(); + } + + return this; + } + + WriteLine(); + var contentSpan = _builder.AsSpan(contentStart, contentEnd - contentStart); + + var lastLineBreak = contentSpan.LastIndexOf(_newLine); + if (lastLineBreak == -1) + { + // Add spaces and dot to match existing formatting + if (contentEnd > contentStart) + { + if (contentSpan[^1] != ' ') + { + InsertRaw(contentSpan[^1] == '.' ? " " : ". ", contentEnd); + } + else + { + var trimmedContentSpan = contentSpan.TrimEnd(); + if (trimmedContentSpan[^1] != '.') + { + InsertRaw(".", contentStart + trimmedContentSpan.Length); + } + } + + if (contentSpan[0] != ' ') + { + InsertRaw(" ", contentStart); + } + } + return this; + } + + if (lastLineBreak != contentSpan.Length) + { + InsertRaw(xmlDocNewLine, contentEnd); + } + + while (lastLineBreak != -1) + { + InsertRaw(xmlDoc, lastLineBreak + contentStart + 1); + contentSpan = contentSpan.Slice(0, lastLineBreak); + lastLineBreak = contentSpan.LastIndexOf(_newLine); + } + + if (contentSpan.Length > 0) + { + InsertRaw(xmlDocNewLine, contentStart); + } + + return this; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriter.cs index 24b5de12b0..3b70e722a0 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriter.cs @@ -5,19 +5,16 @@ using System.Buffers; using System.Collections.Generic; using System.Diagnostics; -using Microsoft.CodeAnalysis.CSharp; using System.Linq; using System.Text; -using System.Runtime.CompilerServices; -using static Microsoft.Generator.CSharp.ValidationType; -using Microsoft.Generator.CSharp.Expressions; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.Generator.CSharp.Expressions; using static Microsoft.Generator.CSharp.Expressions.Snippets; -using Microsoft.Generator.CSharp.Models; namespace Microsoft.Generator.CSharp { - public sealed class CodeWriter + public sealed partial class CodeWriter { private const int DefaultLength = 1024; private static readonly string _newLine = "\n"; @@ -99,53 +96,6 @@ private CodeWriterScope ScopeRaw(string start = "{", string end = "}", bool newL return codeWriterScope; } - private static void AppendTypeWithShortNames(CSharpType type, StringBuilder sb) - { - sb.Append(type.TryGetCSharpFriendlyName(out var keywordName) ? keywordName : type.Name); - - if (type.Arguments.Any()) - { - sb.Append("{"); - foreach (var typeArgument in type.Arguments) - { - AppendTypeWithShortNames(typeArgument, sb); - sb.Append(","); - } - sb.Remove(sb.Length - 1, 1); - sb.Append("}"); - } - - if (type is { IsNullable: true, IsValueType: true }) - { - sb.Append("?"); - } - } - - private CodeWriter WriteXmlDocumentationParametersExceptions(Type exceptionType, IReadOnlyCollection parameters, string reason) - { - if (parameters.Count == 0) - { - return this; - } - - var formatBuilder = new StringBuilder(); - for (var i = 0; i < parameters.Count - 2; ++i) - { - formatBuilder.Append(", "); - } - - if (parameters.Count > 1) - { - formatBuilder.Append(" or "); - } - - formatBuilder.Append(""); - formatBuilder.Append(reason); - - var description = FormattableStringFactory.Create(formatBuilder.ToString(), parameters.Select(p => (object)p.Name).ToArray()); - return WriteXmlDocumentationException(exceptionType, description); - } - public CodeWriterScope SetNamespace(string @namespace) { _currentNamespace = @namespace; @@ -267,40 +217,6 @@ public void WriteMethod(CSharpMethod method) CodeModelPlugin.Instance.CodeWriterExtensionMethods.WriteMethod(this, method); } - public CodeWriter WriteMethodDocumentation(MethodSignatureBase methodBase) - { - if (methodBase.IsRawSummaryText) - { - return WriteRawXmlDocumentation(methodBase.Description); - } - - if (methodBase.NonDocumentComment is { } comment) - { - WriteLine($"// {comment}"); - } - - if (methodBase.SummaryText is { } summaryText) - { - WriteXmlDocumentationSummary(summaryText); - } - - return WriteMethodDocumentationSignature(methodBase); - } - - public CodeWriter WriteMethodDocumentationSignature(MethodSignatureBase methodBase) - { - WriteXmlDocumentationParameters(methodBase.Modifiers.HasFlag(MethodSignatureModifiers.Public) ? methodBase.Parameters : methodBase.Parameters.Where(p => p.Description is not null)); - - WriteXmlDocumentationRequiredParametersException(methodBase.Parameters); - WriteXmlDocumentationNonEmptyParametersException(methodBase.Parameters); - if (methodBase is MethodSignature { ReturnDescription: { } } method) - { - WriteXmlDocumentationReturns(method.ReturnDescription); - } - - return this; - } - public void WriteProperty(PropertyDeclaration property) { if (!CurrentLine.IsEmpty) @@ -550,7 +466,7 @@ public CodeWriter WriteParametersValidation(IEnumerable parameters) private CodeWriter WriteParameterValidation(Parameter parameter) { - if (parameter.Validation == None && parameter.Initializer != null) + if (parameter.Validation == ValidationType.None && parameter.Initializer != null) { return WriteLine($"{parameter.Name:I} ??= {parameter.Initializer};"); } @@ -562,189 +478,6 @@ private CodeWriter WriteParameterValidation(Parameter parameter) return this; } - public CodeWriter WriteXmlDocumentationInheritDoc(CSharpType? crefType = null) - => crefType == null - ? WriteLine($"/// ") - : WriteLine($"/// "); - - public CodeWriter WriteXmlDocumentationSummary(FormattableString? text) - { - return WriteXmlDocumentation("summary", text); - } - - public CodeWriter WriteXmlDocumentation(string tag, FormattableString? text) - { - return WriteDocumentationLines($"<{tag}>", $"", text); - } - - public CodeWriter WriteXmlDocumentationParameters(IEnumerable parameters) - { - foreach (var parameter in parameters) - { - WriteXmlDocumentationParameter(parameter); - } - - return this; - } - - public CodeWriter WriteXmlDocumentationParameter(string name, FormattableString? text) - { - return WriteDocumentationLines($"", $"", text); - } - - /// - /// Writes XML documentation for a parameter of a method using a "param" tag. - /// - /// Writer to which code is written to. - /// The definition of the parameter, including name and description. - /// - public CodeWriter WriteXmlDocumentationParameter(Parameter parameter) - { - return WriteXmlDocumentationParameter(parameter.Name, parameter.Description); - } - - public CodeWriter WriteXmlDocumentationException(CSharpType exception, FormattableString? description) - { - return WriteDocumentationLines($"", $"", description); - } - - public CodeWriter WriteXmlDocumentationReturns(FormattableString text) - { - return WriteDocumentationLines($"", $"", text); - } - - internal CodeWriter WriteXmlDocumentationInclude(string filename, MethodSignature methodSignature, out string memberId) - { - var sb = new StringBuilder(); - sb.Append(methodSignature.Name).Append("("); - foreach (var parameter in methodSignature.Parameters) - { - AppendTypeWithShortNames(parameter.Type, sb); - sb.Append(","); - } - - sb.Remove(sb.Length - 1, 1); - sb.Append(")"); - - memberId = sb.ToString(); - return WriteRawLine($"/// "); - } - - public CodeWriter WriteXmlDocumentationRequiredParametersException(IEnumerable parameters) - { - return WriteXmlDocumentationParametersExceptions(typeof(ArgumentNullException), parameters.Where(p => p.Validation is AssertNotNull or AssertNotNullOrEmpty).ToArray(), " is null."); - } - - public CodeWriter WriteXmlDocumentationNonEmptyParametersException(IEnumerable parameters) - { - return WriteXmlDocumentationParametersExceptions(typeof(ArgumentException), parameters.Where(p => p.Validation == AssertNotNullOrEmpty).ToArray(), " is an empty string, and was expected to be non-empty."); - } - - public CodeWriter WriteDocumentationLines(FormattableString startTag, FormattableString endTag, FormattableString? text) - => AppendXmlDocumentation(startTag, endTag, text ?? $""); - - internal CodeWriter WriteRawXmlDocumentation(FormattableString? content) - { - if (content is null) - return this; - - var lines = content.ToString().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); - var xmlLines = string.Join('\n', lines.Select(l => "/// " + l)); - AppendRaw(xmlLines); - WriteLine(); - return this; - } - - internal CodeWriter AppendXmlDocumentation(FormattableString startTag, FormattableString endTag, FormattableString content) - { - const string xmlDoc = "/// "; - const string xmlDocNewLine = "\n/// "; - - var commentStart = _length; - AppendRaw(CurrentLine.IsEmpty ? xmlDoc : xmlDocNewLine); - - var startTagStart = _length; - Append(startTag); - _writingXmlDocumentation = true; - - var contentStart = _length; - if (content.Format.Length > 0) - { - Append(content); - } - var contentEnd = _length; - - _writingXmlDocumentation = false; - Append(endTag); - - if (contentStart == contentEnd) - { - var startTagSpan = WrittenText.Slice(startTagStart + 1, contentStart - startTagStart - 1); - var endTagSpan = WrittenText.Slice(contentEnd + 2); - - if (startTagSpan.SequenceEqual(endTagSpan)) - { - // Remove empty tags - _length = commentStart; - } - else - { - WriteLine(); - } - - return this; - } - - WriteLine(); - var contentSpan = _builder.AsSpan(contentStart, contentEnd - contentStart); - - var lastLineBreak = contentSpan.LastIndexOf(_newLine); - if (lastLineBreak == -1) - { - // Add spaces and dot to match existing formatting - if (contentEnd > contentStart) - { - if (contentSpan[^1] != ' ') - { - InsertRaw(contentSpan[^1] == '.' ? " " : ". ", contentEnd); - } - else - { - var trimmedContentSpan = contentSpan.TrimEnd(); - if (trimmedContentSpan[^1] != '.') - { - InsertRaw(".", contentStart + trimmedContentSpan.Length); - } - } - - if (contentSpan[0] != ' ') - { - InsertRaw(" ", contentStart); - } - } - return this; - } - - if (lastLineBreak != contentSpan.Length) - { - InsertRaw(xmlDocNewLine, contentEnd); - } - - while (lastLineBreak != -1) - { - InsertRaw(xmlDoc, lastLineBreak + contentStart + 1); - contentSpan = contentSpan.Slice(0, lastLineBreak); - lastLineBreak = contentSpan.LastIndexOf(_newLine); - } - - if (contentSpan.Length > 0) - { - InsertRaw(xmlDocNewLine, contentStart); - } - - return this; - } - internal string GetTemporaryVariable(string s) { if (IsAvailable(s)) diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriterExtensionMethods.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriterExtensionMethods.cs index 9b144b6308..13b9fdcb87 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriterExtensionMethods.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/CodeWriterExtensionMethods.cs @@ -27,13 +27,22 @@ public virtual void WriteMethod(CodeWriter writer, CSharpMethod method) writer.WriteMethodDocumentation(method.Signature); - if (method.Body is { } body) + if (method.BodyStatements is { } body) { using (writer.WriteMethodDeclaration(method.Signature)) { body.Write(writer); } } + else if (method.BodyExpression is { } expression) + { + using (writer.WriteMethodDeclarationNoScope(method.Signature)) + { + writer.AppendRaw(" => "); + expression.Write(writer); + writer.WriteRawLine(";"); + } + } writer.WriteLine(); } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/TypeProviderWriter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/TypeProviderWriter.cs index e483106495..ac8c6fbe7c 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/TypeProviderWriter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Writers/TypeProviderWriter.cs @@ -3,7 +3,7 @@ using System.Linq; -namespace Microsoft.Generator.CSharp.Writers +namespace Microsoft.Generator.CSharp { public class TypeProviderWriter { @@ -71,8 +71,6 @@ private void WriteClassOrStruct() WriteConstructors(); WriteProperties(); - - _writer.WriteLine($"// Add Methods"); // https://github.com/Azure/autorest.csharp/issues/4476 WriteMethods(); _writer.WriteLine($"// Add Nested Type"); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ApiTypesTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ApiTypesTests.cs index d9d6185151..27a677604f 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ApiTypesTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ApiTypesTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using Moq; @@ -17,22 +17,6 @@ public void Setup() { _mock = new Mock(); } - [Test] - public void TestChangeTrackingListType() - { - Assert.IsNotNull(_mock?.Object); - - _mock.Setup(x => x.ChangeTrackingListType).Returns(typeof(int)); - Assert.AreEqual(typeof(int), _mock.Object.ChangeTrackingListType); - } - - [Test] - public void TestChangeTrackingDictionaryType() - { - _mock.Setup(x => x.ChangeTrackingDictionaryType).Returns(typeof(int)); - Assert.AreEqual(typeof(int), _mock.Object.ChangeTrackingDictionaryType); - } - [Test] public void TestEndPointSampleValue() diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpGenTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpGenTests.cs index 2aa3f7551f..f2d7242aa6 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpGenTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpGenTests.cs @@ -71,8 +71,6 @@ public void TestCSharpGen_ValidPlugin() }; mockTypeFactory.Setup(p => p.CreateCSharpType(It.IsAny())).Returns(new CSharpType(typeof(IList<>))); - mockApiTypes.SetupGet(p => p.ChangeTrackingListType).Returns(typeof(IList<>)); - mockApiTypes.SetupGet(p => p.ChangeTrackingDictionaryType).Returns(typeof(IDictionary)); mockExtensibleSnippets.SetupGet(p => p.Model).Returns(new Mock().Object); mockPlugin.SetupGet(p => p.ApiTypes).Returns(mockApiTypes.Object); mockPlugin.SetupGet(p => p.ExtensibleSnippets).Returns(mockExtensibleSnippets.Object); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpMethodCollectionTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpMethodCollectionTests.cs index b218c6a18f..63d503601f 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpMethodCollectionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpMethodCollectionTests.cs @@ -69,20 +69,29 @@ public static IEnumerable DefaultCSharpMethodCollectionTestCases { get { - yield return new TestCaseData(new InputOperation - { - HttpMethod = "GET", - Name = "CreateMessage", - Path = "/api/messages", - RequestBodyMediaType = BodyMediaType.Json, - RequestMediaTypes = new[] { "application/json" }, - GenerateProtocolMethod = true, - GenerateConvenienceMethod = true, - Parameters = new[] - { - new InputParameter("message", "message", "The message to create.", new InputPrimitiveType(InputTypeKind.Boolean), RequestLocation.Body, null, null, InputOperationParameterKind.Method, true, false, false, false, false, false, false, null, null) - } - }, CSharpMethodKinds.CreateMessage); + yield return new TestCaseData(new InputOperation( + name: "CreateMessage", + resourceName: null, + summary: null, + deprecated: null, + description: string.Empty, + accessibility: null, + parameters: [ + new InputParameter("message", "message", "The message to create.", new InputPrimitiveType(InputPrimitiveTypeKind.Boolean), RequestLocation.Body, null, null, InputOperationParameterKind.Method, true, false, false, false, false, false, false, null, null) + ], + responses: Array.Empty(), + httpMethod: "GET", + requestBodyMediaType: BodyMediaType.Json, + uri: "localhost", + path: "/api/messages", + externalDocsUrl: null, + requestMediaTypes: null, + bufferResponse: false, + longRunning: null, + paging: null, + generateProtocolMethod: true, + generateConvenienceMethod: true + ), CSharpMethodKinds.CreateMessage); } } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpTypeTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpTypeTests.cs index 08cdc51995..4b837a58a9 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpTypeTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CSharpTypeTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; @@ -9,7 +9,6 @@ using Moq; using System.IO; using System.Text; -using Microsoft.Generator.CSharp.Expressions; namespace Microsoft.Generator.CSharp.Tests { @@ -26,11 +25,6 @@ public void Setup() CallBase = true }; - Mock extensibleSnippets = new Mock(); - - mockApiTypes.SetupGet(p => p.ChangeTrackingListType).Returns(typeof(IList<>)); - mockApiTypes.SetupGet(p => p.ChangeTrackingDictionaryType).Returns(typeof(IDictionary<,>)); - var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder); // initialize the singleton instance of the plugin _ = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath))); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CodeWriterTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CodeWriterTests.cs index e90da77824..feb17a4624 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CodeWriterTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/CodeWriterTests.cs @@ -3,12 +3,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; -using NUnit.Framework; using Microsoft.Generator.CSharp.Expressions; -using System.IO; -using Microsoft.Generator.CSharp.Models; +using NUnit.Framework; using static Microsoft.Generator.CSharp.Expressions.Snippets; namespace Microsoft.Generator.CSharp.Tests diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ConfigurationTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ConfigurationTests.cs index bbd279342e..09eac38712 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ConfigurationTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/ConfigurationTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -33,8 +33,6 @@ public void TestInitialize() CallBase = true }; - mockApiTypes.SetupGet(p => p.ChangeTrackingListType).Returns(typeof(IList<>)); - mockApiTypes.SetupGet(p => p.ChangeTrackingDictionaryType).Returns(typeof(IDictionary)); mockApiTypes.SetupGet(p => p.EndPointSampleValue).Returns("Sample"); var modelSnippets = new Mock().Object; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Microsoft.Generator.CSharp.Tests.csproj b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Microsoft.Generator.CSharp.Tests.csproj index 908511467b..8aac1c11e3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Microsoft.Generator.CSharp.Tests.csproj +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Microsoft.Generator.CSharp.Tests.csproj @@ -23,11 +23,5 @@ PreserveNewest - - - - PreserveNewest - - diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/PropertyDescriptionTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/PropertyDescriptionTests.cs index 89e0a8f684..1e2340c31b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/PropertyDescriptionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/PropertyDescriptionTests.cs @@ -71,27 +71,27 @@ public static IEnumerable BuildPropertyDescriptionTestCases { // list property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputTypeKind.String, false), false, false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, false), false, false, false), new CSharpType(typeof(IList))); // list of binary data property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputTypeKind.BinaryData, false), false, false), false, true, false), + new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.BinaryData, false), false, false), false, true, false), new CSharpType(typeof(IReadOnlyList))); // dictionary property with binary data value yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputTypeKind.String, false), new InputPrimitiveType(InputTypeKind.BinaryData, false), false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), new InputPrimitiveType(InputPrimitiveTypeKind.BinaryData, false), false), false, false, false), new CSharpType(typeof(IDictionary))); // nullable dictionary property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputTypeKind.String, false), new InputPrimitiveType(InputTypeKind.String, false), false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false), false, false, false), new CSharpType(typeof(IDictionary), true)); // primitive type property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputTypeKind.String, false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, false, false), new CSharpType(typeof(string))); // binary data property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputTypeKind.BinaryData, false), false, true, false), + new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputPrimitiveTypeKind.BinaryData, false), false, true, false), new CSharpType(typeof(BinaryData))); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/Types/ModelTypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/Types/ModelTypeProviderTests.cs index 3b07f5b1ff..2f94a3593b 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/Types/ModelTypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Models/Types/ModelTypeProviderTests.cs @@ -71,42 +71,42 @@ public static IEnumerable BuildProperties_ValidatePropertySettersT { // list property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputTypeKind.String, false), false, false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, false), false, false, false), new CSharpType(typeof(IList)), false); // read only list property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputTypeKind.String, false), false, false), false, true, false), + new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, false), false, true, false), new CSharpType(typeof(IReadOnlyList)), false); // nullable list property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputTypeKind.String, false), false, false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, false), false, false, false), new CSharpType(typeof(IList), true), true); // dictionary property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputTypeKind.String, false), new InputPrimitiveType(InputTypeKind.String, false), false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false), false, false, false), new CSharpType(typeof(IDictionary)), false); // nullable dictionary property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputTypeKind.String, false), new InputPrimitiveType(InputTypeKind.String, false), false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputDictionary("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false), false, false, false), new CSharpType(typeof(IDictionary), true), true); // primitive type property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputTypeKind.String, false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, false, false), new CSharpType(typeof(string)), true); // read only primitive type property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputTypeKind.String, false), false, true, false), + new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, true, false), new CSharpType(typeof(string)), false); // readonlymemory property yield return new TestCaseData( - new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputTypeKind.String, false), true, false), false, false, false), + new InputModelProperty("prop1", "prop1", "public", new InputList("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), true, false), false, false, false), new CSharpType(typeof(ReadOnlyMemory<>)), true); } @@ -120,10 +120,10 @@ private CSharpType GetCSharpType(InputType type) { var primitiveType = (InputPrimitiveType)type; - if (primitiveType.Kind is InputTypeKind.String) + if (primitiveType.Kind is InputPrimitiveTypeKind.String) return new CSharpType(typeof(string)); - if (primitiveType.Kind is InputTypeKind.Int32) + if (primitiveType.Kind is InputPrimitiveTypeKind.Int32) return new CSharpType(typeof(int)); throw new ArgumentException("Unsupported input type."); @@ -148,8 +148,8 @@ public void BuildConstructor_ValidateConstructors() var properties = new List{ new InputModelProperty("requiredString", "requiredString", "", InputPrimitiveType.String, true, false, false), new InputModelProperty("OptionalInt", "optionalInt", "", InputPrimitiveType.Int32, false, false, false), - new InputModelProperty("requiredCollection", "requiredCollection", "", new InputList("List", new InputPrimitiveType(InputTypeKind.String, false), false, false), true, false, false), - new InputModelProperty("requiredDictionary", "requiredDictionary", "", new InputDictionary("Dictionary", new InputPrimitiveType(InputTypeKind.String, false), new InputPrimitiveType(InputTypeKind.String, false), false), true, false, false), + new InputModelProperty("requiredCollection", "requiredCollection", "", new InputList("List", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false, false), true, false, false), + new InputModelProperty("requiredDictionary", "requiredDictionary", "", new InputDictionary("Dictionary", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), new InputPrimitiveType(InputPrimitiveTypeKind.String, false), false), true, false, false), new InputModelProperty("optionalUnknown", "optional unknown", "", new InputIntrinsicType(InputIntrinsicTypeKind.Unknown), false, false, false), }; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/TypeFactoryTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/TypeFactoryTests.cs index 9f4b8bcc18..624838f942 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/TypeFactoryTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/TypeFactoryTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -48,10 +48,10 @@ public static IEnumerable CreateTypeTestCases { get { - yield return new TestCaseData(new InputList("sampleType", new InputPrimitiveType(InputTypeKind.Boolean, false), false, false), new CSharpType(typeof(InputList), isNullable: false), false); - yield return new TestCaseData(new InputDictionary("sampleType", new InputPrimitiveType(InputTypeKind.String, false), new InputPrimitiveType(InputTypeKind.Int32, false), false), new CSharpType(typeof(InputDictionary), isNullable: false), false); - yield return new TestCaseData(new InputPrimitiveType(InputTypeKind.String, false), new CSharpType(typeof(InputPrimitiveType), isNullable: false), false); - yield return new TestCaseData(new InputLiteralType("literalType", new InputPrimitiveType(InputTypeKind.String, false), "literal", false), null, true); + yield return new TestCaseData(new InputList("sampleType", new InputPrimitiveType(InputPrimitiveTypeKind.Boolean, false), false, false), new CSharpType(typeof(InputList), isNullable: false), false); + yield return new TestCaseData(new InputDictionary("sampleType", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), new InputPrimitiveType(InputPrimitiveTypeKind.Int32, false), false), new CSharpType(typeof(InputDictionary), isNullable: false), false); + yield return new TestCaseData(new InputPrimitiveType(InputPrimitiveTypeKind.String, false), new CSharpType(typeof(InputPrimitiveType), isNullable: false), false); + yield return new TestCaseData(new InputLiteralType("literalType", new InputPrimitiveType(InputPrimitiveTypeKind.String, false), "literal", false), null, true); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/ExpressionTypeProviderWriterTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/ExpressionTypeProviderWriterTests.cs index bce172e029..28def86f42 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/ExpressionTypeProviderWriterTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/ExpressionTypeProviderWriterTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using Microsoft.Generator.CSharp.Writers; using Moq; using NUnit.Framework; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/mocks/MockCodeModelPlugin.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/mocks/MockCodeModelPlugin.cs index 9022dd194a..6c84c9c930 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/mocks/MockCodeModelPlugin.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/mocks/MockCodeModelPlugin.cs @@ -1,9 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using Microsoft.Generator.CSharp.Expressions; -using Microsoft.Generator.CSharp.Input; namespace Microsoft.Generator.CSharp.Tests { @@ -23,5 +22,6 @@ public MockCodeModelPlugin(GeneratorContext context) : base(context) public override TypeFactory TypeFactory => throw new NotImplementedException(); public override ExtensibleSnippets ExtensibleSnippets => throw new NotImplementedException(); public override OutputLibrary OutputLibrary => throw new NotImplementedException(); + public override TypeProvider[] GetSerializationTypeProviders(ModelTypeProvider provider) => throw new NotImplementedException(); } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/mocks/tspCodeModel.json b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/mocks/tspCodeModel.json deleted file mode 100644 index 2d8e966996..0000000000 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/mocks/tspCodeModel.json +++ /dev/null @@ -1,2923 +0,0 @@ -{ - "$id": "1", - "Name": "UnbrandedTypeSpec", - "Description": "This is a sample typespec project.", - "ApiVersions": [], - "Enums": [ - { - "$id": "2", - "Kind": "Enum", - "Name": "Thing_requiredLiteralString", - "EnumValueType": "String", - "AllowedValues": [ - { - "$id": "3", - "Name": "accept", - "Value": "accept", - "Description": "accept" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "The Thing_requiredLiteralString", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "4", - "Kind": "Enum", - "Name": "Thing_requiredLiteralInt", - "EnumValueType": "Float32", - "AllowedValues": [ - { - "$id": "5", - "Name": "123", - "Value": 123, - "Description": "123" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "The Thing_requiredLiteralInt", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "6", - "Kind": "Enum", - "Name": "Thing_requiredLiteralFloat", - "EnumValueType": "Float32", - "AllowedValues": [ - { - "$id": "7", - "Name": "1.23", - "Value": 1.23, - "Description": "1.23" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "The Thing_requiredLiteralFloat", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "8", - "Kind": "Enum", - "Name": "Thing_optionalLiteralString", - "EnumValueType": "String", - "AllowedValues": [ - { - "$id": "9", - "Name": "reject", - "Value": "reject", - "Description": "reject" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "The Thing_optionalLiteralString", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "10", - "Kind": "Enum", - "Name": "Thing_optionalLiteralInt", - "EnumValueType": "Float32", - "AllowedValues": [ - { - "$id": "11", - "Name": "456", - "Value": 456, - "Description": "456" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "The Thing_optionalLiteralInt", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "12", - "Kind": "Enum", - "Name": "Thing_optionalLiteralFloat", - "EnumValueType": "Float32", - "AllowedValues": [ - { - "$id": "13", - "Name": "4.56", - "Value": 4.56, - "Description": "4.56" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "The Thing_optionalLiteralFloat", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "14", - "Kind": "Enum", - "Name": "StringFixedEnum", - "EnumValueType": "String", - "AllowedValues": [ - { - "$id": "15", - "Name": "One", - "Value": "1" - }, - { - "$id": "16", - "Name": "Two", - "Value": "2" - }, - { - "$id": "17", - "Name": "Four", - "Value": "4" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "Simple enum", - "IsExtensible": false, - "IsNullable": true, - "Usage": "RoundTrip" - }, - { - "$id": "18", - "Kind": "Enum", - "Name": "StringExtensibleEnum", - "EnumValueType": "string", - "AllowedValues": [ - { - "$id": "19", - "Name": "One", - "Value": "1" - }, - { - "$id": "20", - "Name": "Two", - "Value": "2" - }, - { - "$id": "21", - "Name": "Four", - "Value": "4" - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "Extensible enum", - "IsExtensible": true, - "IsNullable": true, - "Usage": "RoundTrip" - }, - { - "$id": "22", - "Kind": "Enum", - "Name": "IntExtensibleEnum", - "EnumValueType": "int32", - "AllowedValues": [ - { - "$id": "23", - "Name": "One", - "Value": 1 - }, - { - "$id": "24", - "Name": "Two", - "Value": 2 - }, - { - "$id": "25", - "Name": "Four", - "Value": 4 - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "Int based extensible enum", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "26", - "Kind": "Enum", - "Name": "FloatExtensibleEnum", - "EnumValueType": "float32", - "AllowedValues": [ - { - "$id": "27", - "Name": "One", - "Value": 1 - }, - { - "$id": "28", - "Name": "Two", - "Value": 2 - }, - { - "$id": "29", - "Name": "Four", - "Value": 4 - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "Float based extensible enum", - "IsExtensible": true, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "30", - "Kind": "Enum", - "Name": "FloatFixedEnum", - "EnumValueType": "Float32", - "AllowedValues": [ - { - "$id": "31", - "Name": "One", - "Value": 1.1 - }, - { - "$id": "32", - "Name": "Two", - "Value": 2.2 - }, - { - "$id": "33", - "Name": "Four", - "Value": 4.4 - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "float fixed enum", - "IsExtensible": false, - "IsNullable": false, - "Usage": "RoundTrip" - }, - { - "$id": "34", - "Kind": "Enum", - "Name": "IntFixedEnum", - "EnumValueType": "Float32", - "AllowedValues": [ - { - "$id": "35", - "Name": "One", - "Value": 1 - }, - { - "$id": "36", - "Name": "Two", - "Value": 2 - }, - { - "$id": "37", - "Name": "Four", - "Value": 4 - } - ], - "Namespace": "UnbrandedTypeSpec", - "Description": "int fixed enum", - "IsExtensible": false, - "IsNullable": false, - "Usage": "RoundTrip" - } - ], - "Models": [ - { - "$id": "38", - "Kind": "Model", - "Name": "Thing", - "Namespace": "UnbrandedTypeSpec", - "Description": "A model with a few properties of literal types", - "IsNullable": false, - "Usage": "RoundTrip", - "Properties": [ - { - "$id": "39", - "Name": "name", - "SerializedName": "name", - "Description": "name of the Thing", - "Type": { - "$id": "40", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "41", - "Name": "requiredUnion", - "SerializedName": "requiredUnion", - "Description": "required Union", - "Type": { - "$id": "42", - "Kind": "Union", - "Name": "Union", - "UnionItemTypes": [ - { - "$id": "43", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - { - "$id": "44", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$id": "45", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "IsNullable": false - }, - { - "$id": "46", - "Kind": "Primitive", - "Name": "Int32", - "IsNullable": false - } - ], - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "47", - "Name": "requiredLiteralString", - "SerializedName": "requiredLiteralString", - "Description": "required literal string", - "Type": { - "$id": "48", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$ref": "2" - }, - "Value": "accept", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "49", - "Name": "requiredLiteralInt", - "SerializedName": "requiredLiteralInt", - "Description": "required literal int", - "Type": { - "$id": "50", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$ref": "4" - }, - "Value": 123, - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "51", - "Name": "requiredLiteralFloat", - "SerializedName": "requiredLiteralFloat", - "Description": "required literal float", - "Type": { - "$id": "52", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$ref": "6" - }, - "Value": 1.23, - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "53", - "Name": "requiredLiteralBool", - "SerializedName": "requiredLiteralBool", - "Description": "required literal bool", - "Type": { - "$id": "54", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$id": "55", - "Kind": "Primitive", - "Name": "Boolean", - "IsNullable": false - }, - "Value": false, - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "56", - "Name": "optionalLiteralString", - "SerializedName": "optionalLiteralString", - "Description": "optional literal string", - "Type": { - "$id": "57", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$ref": "8" - }, - "Value": "reject", - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "58", - "Name": "optionalLiteralInt", - "SerializedName": "optionalLiteralInt", - "Description": "optional literal int", - "Type": { - "$id": "59", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$ref": "10" - }, - "Value": 456, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "60", - "Name": "optionalLiteralFloat", - "SerializedName": "optionalLiteralFloat", - "Description": "optional literal float", - "Type": { - "$id": "61", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$ref": "12" - }, - "Value": 4.56, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "62", - "Name": "optionalLiteralBool", - "SerializedName": "optionalLiteralBool", - "Description": "optional literal bool", - "Type": { - "$id": "63", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$id": "64", - "Kind": "Primitive", - "Name": "Boolean", - "IsNullable": false - }, - "Value": true, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "65", - "Name": "requiredBadDescription", - "SerializedName": "requiredBadDescription", - "Description": "description with xml <|endoftext|>", - "Type": { - "$id": "66", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "67", - "Name": "optionalNullableList", - "SerializedName": "optionalNullableList", - "Description": "optional nullable collection", - "Type": { - "$id": "68", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$id": "69", - "Kind": "Primitive", - "Name": "Int32", - "IsNullable": false - }, - "IsNullable": true - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "70", - "Name": "requiredNullableList", - "SerializedName": "requiredNullableList", - "Description": "required nullable collection", - "Type": { - "$id": "71", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$id": "72", - "Kind": "Primitive", - "Name": "Int32", - "IsNullable": false - }, - "IsNullable": true - }, - "IsRequired": true, - "IsReadOnly": false - } - ] - }, - { - "$id": "73", - "Kind": "Model", - "Name": "RoundTripModel", - "Namespace": "UnbrandedTypeSpec", - "Description": "this is a roundtrip model", - "IsNullable": false, - "Usage": "RoundTrip", - "Properties": [ - { - "$id": "74", - "Name": "requiredString", - "SerializedName": "requiredString", - "Description": "Required string, illustrating a reference type property.", - "Type": { - "$id": "75", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "76", - "Name": "requiredInt", - "SerializedName": "requiredInt", - "Description": "Required int, illustrating a value type property.", - "Type": { - "$id": "77", - "Kind": "Primitive", - "Name": "Int32", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "78", - "Name": "requiredCollection", - "SerializedName": "requiredCollection", - "Description": "Required collection of enums", - "Type": { - "$id": "79", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$ref": "14" - }, - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "80", - "Name": "requiredDictionary", - "SerializedName": "requiredDictionary", - "Description": "Required dictionary of enums", - "Type": { - "$id": "81", - "Kind": "Dictionary", - "Name": "Dictionary", - "KeyType": { - "$id": "82", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "ValueType": { - "$ref": "18" - }, - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "83", - "Name": "requiredModel", - "SerializedName": "requiredModel", - "Description": "Required model", - "Type": { - "$ref": "38" - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "84", - "Name": "intExtensibleEnum", - "SerializedName": "intExtensibleEnum", - "Description": "this is an int based extensible enum", - "Type": { - "$ref": "22" - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "85", - "Name": "intExtensibleEnumCollection", - "SerializedName": "intExtensibleEnumCollection", - "Description": "this is a collection of int based extensible enum", - "Type": { - "$id": "86", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$ref": "22" - }, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "87", - "Name": "floatExtensibleEnum", - "SerializedName": "floatExtensibleEnum", - "Description": "this is a float based extensible enum", - "Type": { - "$ref": "26" - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "88", - "Name": "floatExtensibleEnumCollection", - "SerializedName": "floatExtensibleEnumCollection", - "Description": "this is a collection of float based extensible enum", - "Type": { - "$id": "89", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$ref": "26" - }, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "90", - "Name": "floatFixedEnum", - "SerializedName": "floatFixedEnum", - "Description": "this is a float based fixed enum", - "Type": { - "$ref": "30" - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "91", - "Name": "floatFixedEnumCollection", - "SerializedName": "floatFixedEnumCollection", - "Description": "this is a collection of float based fixed enum", - "Type": { - "$id": "92", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$ref": "30" - }, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "93", - "Name": "intFixedEnum", - "SerializedName": "intFixedEnum", - "Description": "this is a int based fixed enum", - "Type": { - "$ref": "34" - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "94", - "Name": "intFixedEnumCollection", - "SerializedName": "intFixedEnumCollection", - "Description": "this is a collection of int based fixed enum", - "Type": { - "$id": "95", - "Kind": "Array", - "Name": "Array", - "ElementType": { - "$ref": "34" - }, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "96", - "Name": "stringFixedEnum", - "SerializedName": "stringFixedEnum", - "Description": "this is a string based fixed enum", - "Type": { - "$ref": "14" - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "97", - "Name": "requiredUnknown", - "SerializedName": "requiredUnknown", - "Description": "required unknown", - "Type": { - "$id": "98", - "Kind": "Intrinsic", - "Name": "unknown", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "99", - "Name": "optionalUnknown", - "SerializedName": "optionalUnknown", - "Description": "optional unknown", - "Type": { - "$id": "100", - "Kind": "Intrinsic", - "Name": "unknown", - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "101", - "Name": "requiredRecordUnknown", - "SerializedName": "requiredRecordUnknown", - "Description": "required record of unknown", - "Type": { - "$id": "102", - "Kind": "Dictionary", - "Name": "Dictionary", - "KeyType": { - "$id": "103", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "ValueType": { - "$id": "104", - "Kind": "Intrinsic", - "Name": "unknown", - "IsNullable": false - }, - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "105", - "Name": "optionalRecordUnknown", - "SerializedName": "optionalRecordUnknown", - "Description": "optional record of unknown", - "Type": { - "$id": "106", - "Kind": "Dictionary", - "Name": "Dictionary", - "KeyType": { - "$id": "107", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "ValueType": { - "$id": "108", - "Kind": "Intrinsic", - "Name": "unknown", - "IsNullable": false - }, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": false - }, - { - "$id": "109", - "Name": "readOnlyRequiredRecordUnknown", - "SerializedName": "readOnlyRequiredRecordUnknown", - "Description": "required readonly record of unknown", - "Type": { - "$id": "110", - "Kind": "Dictionary", - "Name": "Dictionary", - "KeyType": { - "$id": "111", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "ValueType": { - "$id": "112", - "Kind": "Intrinsic", - "Name": "unknown", - "IsNullable": false - }, - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": true - }, - { - "$id": "113", - "Name": "readOnlyOptionalRecordUnknown", - "SerializedName": "readOnlyOptionalRecordUnknown", - "Description": "optional readonly record of unknown", - "Type": { - "$id": "114", - "Kind": "Dictionary", - "Name": "Dictionary", - "KeyType": { - "$id": "115", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "ValueType": { - "$id": "116", - "Kind": "Intrinsic", - "Name": "unknown", - "IsNullable": false - }, - "IsNullable": false - }, - "IsRequired": false, - "IsReadOnly": true - }, - { - "$id": "117", - "Name": "modelWithRequiredNullable", - "SerializedName": "modelWithRequiredNullable", - "Description": "this is a model with required nullable properties", - "Type": { - "$id": "118", - "Kind": "Model", - "Name": "ModelWithRequiredNullableProperties", - "Namespace": "UnbrandedTypeSpec", - "Description": "A model with a few required nullable properties", - "IsNullable": false, - "Usage": "RoundTrip", - "Properties": [ - { - "$id": "119", - "Name": "requiredNullablePrimitive", - "SerializedName": "requiredNullablePrimitive", - "Description": "required nullable primitive type", - "Type": { - "$id": "120", - "Kind": "Primitive", - "Name": "Int32", - "IsNullable": true - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "121", - "Name": "requiredExtensibleEnum", - "SerializedName": "requiredExtensibleEnum", - "Description": "required nullable extensible enum type", - "Type": { - "$ref": "18" - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "122", - "Name": "requiredFixedEnum", - "SerializedName": "requiredFixedEnum", - "Description": "required nullable fixed enum type", - "Type": { - "$ref": "14" - }, - "IsRequired": true, - "IsReadOnly": false - } - ] - }, - "IsRequired": true, - "IsReadOnly": false - } - ] - }, - { - "$ref": "118" - }, - { - "$id": "123", - "Kind": "Model", - "Name": "Friend", - "Namespace": "UnbrandedTypeSpec", - "Description": "this is not a friendly model but with a friendly name", - "IsNullable": false, - "Usage": "RoundTrip", - "Properties": [ - { - "$id": "124", - "Name": "name", - "SerializedName": "name", - "Description": "name of the NotFriend", - "Type": { - "$id": "125", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - } - ] - }, - { - "$id": "126", - "Kind": "Model", - "Name": "ModelWithFormat", - "Namespace": "UnbrandedTypeSpec", - "IsNullable": false, - "Usage": "Input", - "Properties": [ - { - "$id": "127", - "Name": "sourceUrl", - "SerializedName": "sourceUrl", - "Description": "url format", - "Type": { - "$id": "128", - "Kind": "Primitive", - "Name": "Uri", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - }, - { - "$id": "129", - "Name": "guid", - "SerializedName": "guid", - "Description": "uuid format", - "Type": { - "$id": "130", - "Kind": "Primitive", - "Name": "Guid", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - } - ] - }, - { - "$id": "131", - "Kind": "Model", - "Name": "ProjectedModel", - "Namespace": "UnbrandedTypeSpec", - "Description": "this is a model with a projected name", - "IsNullable": false, - "Usage": "RoundTrip", - "Properties": [ - { - "$id": "132", - "Name": "name", - "SerializedName": "name", - "Description": "name of the ModelWithProjectedName", - "Type": { - "$id": "133", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "IsRequired": true, - "IsReadOnly": false - } - ] - }, - { - "$id": "134", - "Kind": "Model", - "Name": "ReturnsAnonymousModelResponse", - "Namespace": "UnbrandedTypeSpec", - "IsNullable": false, - "Usage": "Output", - "Properties": [] - } - ], - "Clients": [ - { - "$id": "135", - "Name": "UnbrandedTypeSpecClient", - "Description": "This is a sample typespec project.", - "Operations": [ - { - "$id": "136", - "Name": "sayHi", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Return hi", - "Parameters": [ - { - "$id": "137", - "Name": "unbrandedTypeSpecUrl", - "NameInRequest": "unbrandedTypeSpecUrl", - "Type": { - "$id": "138", - "Kind": "Primitive", - "Name": "Uri", - "IsNullable": false - }, - "Location": "Uri", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": true, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Client" - }, - { - "$id": "139", - "Name": "headParameter", - "NameInRequest": "head-parameter", - "Type": { - "$id": "140", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "141", - "Name": "queryParameter", - "NameInRequest": "queryParameter", - "Type": { - "$id": "142", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Query", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "143", - "Name": "optionalQuery", - "NameInRequest": "optionalQuery", - "Type": { - "$id": "144", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Query", - "IsRequired": false, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "145", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "146", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "147", - "Type": { - "$ref": "146" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "148", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/hello", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": false - }, - { - "$id": "149", - "Name": "helloAgain", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Return hi again", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "150", - "Name": "p1", - "NameInRequest": "p1", - "Type": { - "$id": "151", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "152", - "Name": "contentType", - "NameInRequest": "content-type", - "Type": { - "$id": "153", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$id": "154", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Value": "text/plain", - "IsNullable": false - }, - "Location": "Header", - "DefaultValue": { - "$id": "155", - "Type": { - "$ref": "153" - }, - "Value": "text/plain" - }, - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant" - }, - { - "$id": "156", - "Name": "p2", - "NameInRequest": "p2", - "Type": { - "$id": "157", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Path", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "158", - "Name": "action", - "NameInRequest": "action", - "Type": { - "$ref": "73" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "159", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "160", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "161", - "Type": { - "$ref": "160" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "162", - "StatusCodes": [200], - "BodyType": { - "$ref": "73" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/againHi/{p2}", - "RequestMediaTypes": ["text/plain"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "163", - "Name": "noContentType", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Return hi again", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "164", - "Name": "p1", - "NameInRequest": "p1", - "Type": { - "$id": "165", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "166", - "Name": "p2", - "NameInRequest": "p2", - "Type": { - "$id": "167", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Path", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "168", - "Name": "action", - "NameInRequest": "action", - "Type": { - "$ref": "73" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "169", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "170", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "171", - "Type": { - "$ref": "170" - }, - "Value": "application/json" - } - }, - { - "$id": "172", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "173", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "174", - "Type": { - "$ref": "173" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "175", - "StatusCodes": [200], - "BodyType": { - "$ref": "73" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/noContentType/{p2}", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": false - }, - { - "$id": "176", - "Name": "helloDemo2", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Return hi in demo2", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "177", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "178", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "179", - "Type": { - "$ref": "178" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "180", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/demoHi", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "181", - "Name": "createLiteral", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Create with literal value", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "182", - "Name": "body", - "NameInRequest": "body", - "Type": { - "$ref": "38" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "183", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "184", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "185", - "Type": { - "$ref": "184" - }, - "Value": "application/json" - } - }, - { - "$id": "186", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "187", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "188", - "Type": { - "$ref": "187" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "189", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "POST", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/literal", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "190", - "Name": "helloLiteral", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Send literal parameters", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "191", - "Name": "p1", - "NameInRequest": "p1", - "Type": { - "$id": "192", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$id": "193", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Value": "test", - "IsNullable": false - }, - "Location": "Header", - "DefaultValue": { - "$id": "194", - "Type": { - "$ref": "192" - }, - "Value": "test" - }, - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant" - }, - { - "$id": "195", - "Name": "p2", - "NameInRequest": "p2", - "Type": { - "$id": "196", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$id": "197", - "Kind": "Primitive", - "Name": "Int32", - "IsNullable": false - }, - "Value": 123, - "IsNullable": false - }, - "Location": "Path", - "DefaultValue": { - "$id": "198", - "Type": { - "$ref": "196" - }, - "Value": 123 - }, - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant" - }, - { - "$id": "199", - "Name": "p3", - "NameInRequest": "p3", - "Type": { - "$id": "200", - "Kind": "Literal", - "Name": "Literal", - "LiteralValueType": { - "$id": "201", - "Kind": "Primitive", - "Name": "Boolean", - "IsNullable": false - }, - "Value": true, - "IsNullable": false - }, - "Location": "Query", - "DefaultValue": { - "$id": "202", - "Type": { - "$ref": "200" - }, - "Value": true - }, - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant" - }, - { - "$id": "203", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "204", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "205", - "Type": { - "$ref": "204" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "206", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/helloLiteral/{p2}", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "207", - "Name": "topAction", - "ResourceName": "UnbrandedTypeSpec", - "Description": "top level method", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "208", - "Name": "action", - "NameInRequest": "action", - "Type": { - "$id": "209", - "Kind": "Primitive", - "Name": "DateTime", - "IsNullable": false - }, - "Location": "Path", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "210", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "211", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "212", - "Type": { - "$ref": "211" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "213", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/top/{action}", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "214", - "Name": "topAction2", - "ResourceName": "UnbrandedTypeSpec", - "Description": "top level method2", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "215", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "216", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "217", - "Type": { - "$ref": "216" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "218", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/top2", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": false - }, - { - "$id": "219", - "Name": "patchAction", - "ResourceName": "UnbrandedTypeSpec", - "Description": "top level patch", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "220", - "Name": "body", - "NameInRequest": "body", - "Type": { - "$ref": "38" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "221", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "222", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "223", - "Type": { - "$ref": "222" - }, - "Value": "application/json" - } - }, - { - "$id": "224", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "225", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "226", - "Type": { - "$ref": "225" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "227", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "PATCH", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/patch", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": false - }, - { - "$id": "228", - "Name": "anonymousBody", - "ResourceName": "UnbrandedTypeSpec", - "Description": "body parameter without body decorator", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "229", - "Name": "Thing", - "NameInRequest": "Thing", - "Description": "A model with a few properties of literal types", - "Type": { - "$ref": "38" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "230", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "231", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "232", - "Type": { - "$ref": "231" - }, - "Value": "application/json" - } - }, - { - "$id": "233", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "234", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "235", - "Type": { - "$ref": "234" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "236", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "POST", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/anonymousBody", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "237", - "Name": "friendlyModel", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Model can have its friendly name", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "238", - "Name": "Friend", - "NameInRequest": "NotFriend", - "Description": "this is not a friendly model but with a friendly name", - "Type": { - "$ref": "123" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "239", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "240", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "241", - "Type": { - "$ref": "240" - }, - "Value": "application/json" - } - }, - { - "$id": "242", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "243", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "244", - "Type": { - "$ref": "243" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "245", - "StatusCodes": [200], - "BodyType": { - "$ref": "123" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "POST", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/friendlyName", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "246", - "Name": "addTimeHeader", - "ResourceName": "UnbrandedTypeSpec", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "247", - "Name": "repeatabilityFirstSent", - "NameInRequest": "Repeatability-First-Sent", - "Type": { - "$id": "248", - "Kind": "Primitive", - "Name": "DateTime", - "IsNullable": false - }, - "Location": "Header", - "IsRequired": false, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "249", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "250", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "251", - "Type": { - "$ref": "250" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "252", - "StatusCodes": [204], - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": false - }, - { - "$id": "253", - "Name": "stringFormat", - "ResourceName": "UnbrandedTypeSpec", - "Description": "parameter has string format.", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "254", - "Name": "subscriptionId", - "NameInRequest": "subscriptionId", - "Type": { - "$id": "255", - "Kind": "Primitive", - "Name": "Guid", - "IsNullable": false - }, - "Location": "Path", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "256", - "Name": "body", - "NameInRequest": "body", - "Type": { - "$ref": "126" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "257", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "258", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "259", - "Type": { - "$ref": "258" - }, - "Value": "application/json" - } - }, - { - "$id": "260", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "261", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "262", - "Type": { - "$ref": "261" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "263", - "StatusCodes": [204], - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false - } - ], - "HttpMethod": "POST", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/stringFormat/{subscriptionId}", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "264", - "Name": "projectedNameModel", - "ResourceName": "UnbrandedTypeSpec", - "Description": "Model can have its projected name", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "265", - "Name": "ProjectedModel", - "NameInRequest": "ModelWithProjectedName", - "Description": "this is a model with a projected name", - "Type": { - "$ref": "131" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "266", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "267", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "268", - "Type": { - "$ref": "267" - }, - "Value": "application/json" - } - }, - { - "$id": "269", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "270", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "271", - "Type": { - "$ref": "270" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "272", - "StatusCodes": [200], - "BodyType": { - "$ref": "131" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "POST", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/projectedName", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "273", - "Name": "returnsAnonymousModel", - "ResourceName": "UnbrandedTypeSpec", - "Description": "return anonymous model", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "274", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "275", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "276", - "Type": { - "$ref": "275" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "277", - "StatusCodes": [200], - "BodyType": { - "$ref": "134" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "POST", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/returnsAnonymousModel", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - }, - { - "$id": "278", - "Name": "getUnknownValue", - "ResourceName": "UnbrandedTypeSpec", - "Description": "get extensible enum", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "279", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "280", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "281", - "Type": { - "$ref": "280" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "282", - "StatusCodes": [200], - "BodyType": { - "$id": "283", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/unknown-value", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": false - }, - { - "$id": "284", - "Name": "internalProtocol", - "ResourceName": "UnbrandedTypeSpec", - "Description": "When set protocol false and convenient true, then the protocol method should be internal", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "285", - "Name": "body", - "NameInRequest": "body", - "Type": { - "$ref": "38" - }, - "Location": "Body", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "286", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "287", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "288", - "Type": { - "$ref": "287" - }, - "Value": "application/json" - } - }, - { - "$id": "289", - "Name": "contentType", - "NameInRequest": "Content-Type", - "Type": { - "$id": "290", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": true, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "291", - "Type": { - "$ref": "290" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "292", - "StatusCodes": [200], - "BodyType": { - "$ref": "38" - }, - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false, - "ContentTypes": ["application/json"] - } - ], - "HttpMethod": "POST", - "RequestBodyMediaType": "Json", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/internalProtocol", - "RequestMediaTypes": ["application/json"], - "BufferResponse": true, - "GenerateProtocolMethod": false, - "GenerateConvenienceMethod": true - }, - { - "$id": "293", - "Name": "stillConvenient", - "ResourceName": "UnbrandedTypeSpec", - "Description": "When set protocol false and convenient true, the convenient method should be generated even it has the same signature as protocol one", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "294", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "295", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "296", - "Type": { - "$ref": "295" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "297", - "StatusCodes": [204], - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false - } - ], - "HttpMethod": "GET", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/stillConvenient", - "BufferResponse": true, - "GenerateProtocolMethod": false, - "GenerateConvenienceMethod": true - }, - { - "$id": "298", - "Name": "headAsBoolean", - "ResourceName": "UnbrandedTypeSpec", - "Description": "head as boolean.", - "Parameters": [ - { - "$ref": "137" - }, - { - "$id": "299", - "Name": "id", - "NameInRequest": "id", - "Type": { - "$id": "300", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Path", - "IsRequired": true, - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Method" - }, - { - "$id": "301", - "Name": "accept", - "NameInRequest": "Accept", - "Type": { - "$id": "302", - "Kind": "Primitive", - "Name": "String", - "IsNullable": false - }, - "Location": "Header", - "IsApiVersion": false, - "IsResourceParameter": false, - "IsContentType": false, - "IsRequired": true, - "IsEndpoint": false, - "SkipUrlEncoding": false, - "Explode": false, - "Kind": "Constant", - "DefaultValue": { - "$id": "303", - "Type": { - "$ref": "302" - }, - "Value": "application/json" - } - } - ], - "Responses": [ - { - "$id": "304", - "StatusCodes": [204], - "BodyMediaType": "Json", - "Headers": [], - "IsErrorResponse": false - } - ], - "HttpMethod": "HEAD", - "RequestBodyMediaType": "None", - "Uri": "{unbrandedTypeSpecUrl}", - "Path": "/headAsBoolean/{id}", - "BufferResponse": true, - "GenerateProtocolMethod": true, - "GenerateConvenienceMethod": true - } - ], - "Protocol": { - "$id": "305" - }, - "Creatable": true - } - ], - "Auth": { - "$id": "306", - "ApiKey": { - "$id": "307", - "Name": "my-api-key" - } - } -} diff --git a/packages/http-client-csharp/generator/Packages.Data.props b/packages/http-client-csharp/generator/Packages.Data.props index 857c7fd8ea..f4081eb5a8 100644 --- a/packages/http-client-csharp/generator/Packages.Data.props +++ b/packages/http-client-csharp/generator/Packages.Data.props @@ -15,7 +15,7 @@ - + diff --git a/packages/http-client-csharp/generator/TestProjects/Local/TestProjects.Local.Tests.csproj b/packages/http-client-csharp/generator/TestProjects/Local/TestProjects.Local.Tests.csproj index c88da94da2..356b51c4f8 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/TestProjects.Local.Tests.csproj +++ b/packages/http-client-csharp/generator/TestProjects/Local/TestProjects.Local.Tests.csproj @@ -7,6 +7,7 @@ + @@ -18,5 +19,5 @@ - + diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Friend.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Friend.Serialization.cs new file mode 100644 index 0000000000..76fe547c40 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Friend.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace UnbrandedTypeSpec.Models +{ + public partial class Friend : System.ClientModel.Primitives.IJsonModel + { + void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + } + + Friend System.ClientModel.Primitives.IJsonModel.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new Friend(); + } + + System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new System.BinaryData("IPersistableModel"); + } + + Friend System.ClientModel.Primitives.IPersistableModel.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new Friend(); + } + + string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; + + // Add Nested Type + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Friend.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Friend.cs index ebd5d98e96..16a9f3cdf1 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Friend.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Friend.cs @@ -29,8 +29,6 @@ internal Friend() /// name of the NotFriend. public string Name { get; set; } - // Add Methods - // Add Nested Type } } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.Serialization.cs new file mode 100644 index 0000000000..3fa2d04355 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace UnbrandedTypeSpec.Models +{ + public partial class ModelWithFormat : System.ClientModel.Primitives.IJsonModel + { + void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + } + + ModelWithFormat System.ClientModel.Primitives.IJsonModel.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ModelWithFormat(); + } + + System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new System.BinaryData("IPersistableModel"); + } + + ModelWithFormat System.ClientModel.Primitives.IPersistableModel.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ModelWithFormat(); + } + + string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; + + // Add Nested Type + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs index 8b84afb74a..9b026532ff 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs @@ -34,8 +34,6 @@ internal ModelWithFormat() /// uuid format. public Guid Guid { get; set; } - // Add Methods - // Add Nested Type } } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs new file mode 100644 index 0000000000..e11cc933ad --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace UnbrandedTypeSpec.Models +{ + public partial class ModelWithRequiredNullableProperties : System.ClientModel.Primitives.IJsonModel + { + void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + } + + ModelWithRequiredNullableProperties System.ClientModel.Primitives.IJsonModel.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ModelWithRequiredNullableProperties(); + } + + System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new System.BinaryData("IPersistableModel"); + } + + ModelWithRequiredNullableProperties System.ClientModel.Primitives.IPersistableModel.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ModelWithRequiredNullableProperties(); + } + + string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; + + // Add Nested Type + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.cs index 8f6562074d..8cf51f3c77 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.cs @@ -31,8 +31,6 @@ internal ModelWithRequiredNullableProperties() /// required nullable fixed enum type. public string RequiredFixedEnum { get; set; } - // Add Methods - // Add Nested Type } } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.Serialization.cs new file mode 100644 index 0000000000..777f0e298c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace UnbrandedTypeSpec.Models +{ + public partial class ProjectedModel : System.ClientModel.Primitives.IJsonModel + { + void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + } + + ProjectedModel System.ClientModel.Primitives.IJsonModel.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ProjectedModel(); + } + + System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new System.BinaryData("IPersistableModel"); + } + + ProjectedModel System.ClientModel.Primitives.IPersistableModel.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ProjectedModel(); + } + + string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; + + // Add Nested Type + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs index 4fd29cc248..b8b9811807 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs @@ -29,8 +29,6 @@ internal ProjectedModel() /// name of the ModelWithProjectedName. public string Name { get; set; } - // Add Methods - // Add Nested Type } } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ReturnsAnonymousModelResponse.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ReturnsAnonymousModelResponse.Serialization.cs new file mode 100644 index 0000000000..611f3828f1 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ReturnsAnonymousModelResponse.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace UnbrandedTypeSpec.Models +{ + public partial class ReturnsAnonymousModelResponse : System.ClientModel.Primitives.IJsonModel + { + void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + } + + ReturnsAnonymousModelResponse System.ClientModel.Primitives.IJsonModel.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ReturnsAnonymousModelResponse(); + } + + System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new System.BinaryData("IPersistableModel"); + } + + ReturnsAnonymousModelResponse System.ClientModel.Primitives.IPersistableModel.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new ReturnsAnonymousModelResponse(); + } + + string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; + + // Add Nested Type + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ReturnsAnonymousModelResponse.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ReturnsAnonymousModelResponse.cs index 4f346dab19..9b870a5b3f 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ReturnsAnonymousModelResponse.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/ReturnsAnonymousModelResponse.cs @@ -11,8 +11,6 @@ internal ReturnsAnonymousModelResponse() { } - // Add Methods - // Add Nested Type } } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs new file mode 100644 index 0000000000..764b2ccc4c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace UnbrandedTypeSpec.Models +{ + public partial class RoundTripModel : System.ClientModel.Primitives.IJsonModel + { + void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + } + + RoundTripModel System.ClientModel.Primitives.IJsonModel.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new RoundTripModel(); + } + + System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new System.BinaryData("IPersistableModel"); + } + + RoundTripModel System.ClientModel.Primitives.IPersistableModel.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new RoundTripModel(); + } + + string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; + + // Add Nested Type + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs index 381e9c7c1e..2d9194ce18 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs @@ -383,8 +383,6 @@ internal RoundTripModel() /// public System.BinaryData RequiredBytes { get; set; } - // Add Methods - // Add Nested Type } } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Thing.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Thing.Serialization.cs new file mode 100644 index 0000000000..1264324873 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Thing.Serialization.cs @@ -0,0 +1,36 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace UnbrandedTypeSpec.Models +{ + public partial class Thing : System.ClientModel.Primitives.IJsonModel + { + void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + } + + Thing System.ClientModel.Primitives.IJsonModel.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new Thing(); + } + + System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new System.BinaryData("IPersistableModel"); + } + + Thing System.ClientModel.Primitives.IPersistableModel.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) + { + return new Thing(); + } + + string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; + + // Add Nested Type + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Thing.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Thing.cs index 2be9da3be6..6cf99312b2 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Thing.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/Models/Thing.cs @@ -156,8 +156,6 @@ internal Thing() /// required nullable collection. public IList RequiredNullableList { get; set; } - // Add Methods - // Add Nested Type } } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs index bf58bb7645..c7ea812cc0 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs @@ -8,7 +8,6 @@ namespace UnbrandedTypeSpec.Models { public partial class UnbrandedTypeSpecClient { - // Add Methods /// Return hi. /// /// @@ -120,6 +119,7 @@ internal void CreateFriendlyModelRequest(System.Uri unbrandedTypeSpecUrl, Friend { } + /// addTimeHeader. /// /// /// diff --git a/packages/http-client-csharp/package-lock.json b/packages/http-client-csharp/package-lock.json index 70d03d7ae5..07c39f98d7 100644 --- a/packages/http-client-csharp/package-lock.json +++ b/packages/http-client-csharp/package-lock.json @@ -13,7 +13,7 @@ }, "devDependencies": { "@azure-tools/typespec-azure-core": "0.42.0", - "@azure-tools/typespec-client-generator-core": "0.42.2", + "@azure-tools/typespec-client-generator-core": "0.42.3", "@microsoft/api-extractor": "^7.40.3", "@types/node": "~18.13.0", "@typespec/compiler": "0.56.0", @@ -74,9 +74,9 @@ } }, "node_modules/@azure-tools/typespec-client-generator-core": { - "version": "0.42.2", - "resolved": "https://registry.npmjs.org/@azure-tools/typespec-client-generator-core/-/typespec-client-generator-core-0.42.2.tgz", - "integrity": "sha512-Hei86GqNFfKpFhivZPpKo1ktSRQMnZKjLoMwIumklmMpeo5KgyzEgRSpJEiS+zmPZELs2Fu07VgfvpW0IXurUg==", + "version": "0.42.3", + "resolved": "https://registry.npmjs.org/@azure-tools/typespec-client-generator-core/-/typespec-client-generator-core-0.42.3.tgz", + "integrity": "sha512-ZDVVIY1uJ8EaI4QhCdQmTdKVACm4xYn/I7ySpwv4oxk9X8kZFhxx+PKNHAlx34mhOf4oF0PW3wCN5DMeU6asYg==", "dev": true, "dependencies": { "change-case": "~5.4.4", diff --git a/packages/http-client-csharp/package.json b/packages/http-client-csharp/package.json index 8045e1a90b..110188b1c3 100644 --- a/packages/http-client-csharp/package.json +++ b/packages/http-client-csharp/package.json @@ -28,10 +28,10 @@ "build": "npm run build:emitter && npm run build:generator && npm run extract-api", "watch": "tsc -p ./emitter/tsconfig.build.json --watch", "lint-typespec-library": "tsp compile . --warn-as-error --import @typespec/library-linter --no-emit", - "test": "vitest run", - "test:watch": "vitest -w", - "test:ui": "vitest --ui", - "test:ci": "vitest run --coverage --reporter=junit --reporter=default", + "test": "vitest run -c ./emitter/vitest.config.ts", + "test:watch": "vitest -w -c ./emitter/vitest.config.ts", + "test:ui": "vitest --ui -c ./emitter/vitest.config.ts", + "test:ci": "vitest run -c ./emitter/vitest.config.ts --coverage --reporter=junit --reporter=default", "lint": "eslint . --max-warnings=0", "lint:fix": "eslint . --fix", "format": "pnpm -w format:dir packages/http-client-csharp", @@ -54,7 +54,7 @@ }, "devDependencies": { "@azure-tools/typespec-azure-core": "0.42.0", - "@azure-tools/typespec-client-generator-core": "0.42.2", + "@azure-tools/typespec-client-generator-core": "0.42.3", "@microsoft/api-extractor": "^7.40.3", "@types/node": "~18.13.0", "@typespec/compiler": "0.56.0", diff --git a/packages/versioning/src/validate.ts b/packages/versioning/src/validate.ts index c22dc38efc..7149b2c937 100644 --- a/packages/versioning/src/validate.ts +++ b/packages/versioning/src/validate.ts @@ -786,6 +786,7 @@ function validateAvailabilityForContains( for (const key of keySet) { const sourceVal = sourceAvail.get(key)!; const targetVal = targetAvail.get(key)!; + if (sourceVal === targetVal) continue; if ( [Availability.Added].includes(targetVal) && [Availability.Removed, Availability.Unavailable].includes(sourceVal) diff --git a/packages/versioning/src/versioning.ts b/packages/versioning/src/versioning.ts index 62fc7fec7f..a26dab639b 100644 --- a/packages/versioning/src/versioning.ts +++ b/packages/versioning/src/versioning.ts @@ -15,6 +15,7 @@ import { Type, Union, UnionVariant, + compilerAssert, getNamespaceFullName, } from "@typespec/compiler"; import { @@ -806,10 +807,27 @@ export function getAvailabilityMap( ) return undefined; + let parentMap: Map | undefined = undefined; + if (type.kind === "ModelProperty" && type.model !== undefined) { + parentMap = getAvailabilityMap(program, type.model); + } else if (type.kind === "Operation" && type.interface !== undefined) { + parentMap = getAvailabilityMap(program, type.interface); + } + // implicitly, all versioned things are assumed to have been added at // v1 if not specified if (!added.length) { - added.push(allVersions[0]); + if (parentMap !== undefined) { + parentMap.forEach((key, value) => { + if (key === Availability.Added.valueOf()) { + const match = allVersions.find((x) => x.name === value); + compilerAssert(match !== undefined, "Version not found"); + added.push(match); + } + }); + } else { + added.push(allVersions[0]); + } } // something isn't available by default diff --git a/packages/versioning/test/versioning.test.ts b/packages/versioning/test/versioning.test.ts index a2ee45d410..102055e31a 100644 --- a/packages/versioning/test/versioning.test.ts +++ b/packages/versioning/test/versioning.test.ts @@ -280,6 +280,34 @@ describe("versioning: logic", () => { ); }); + it("can be removed respecting model versioning", async () => { + const { + source, + projections: [v2, v3, v4], + } = await versionedModel( + ["v2", "v3", "v4"], + `@added(Versions.v2) + model Test { + a: int32; + @removed(Versions.v3) b: int32; + } + ` + ); + + assertHasProperties(v2, ["a", "b"]); + assertHasProperties(v3, ["a"]); + assertHasProperties(v4, ["a"]); + + assertModelProjectsTo( + [ + [v2, "v2"], + [v3, "v3"], + [v3, "v4"], + ], + source + ); + }); + it("can be renamed", async () => { const { source, @@ -1365,6 +1393,31 @@ describe("versioning: logic", () => { ); }); + it("can be removed respecting interface versioning", async () => { + const { + source, + projections: [v2, v3, v4], + } = await versionedInterface( + ["v2", "v3", "v4"], + `@added(Versions.v2) + interface Test { + allVersions(): void; + @removed(Versions.v3) version2Only(): void; + } + ` + ); + assertHasOperations(v2, ["allVersions", "version2Only"]); + assertHasOperations(v3, ["allVersions"]); + assertInterfaceProjectsTo( + [ + [v2, "v2"], + [v3, "v3"], + [v4, "v4"], + ], + source + ); + }); + it("can be renamed", async () => { const { source,