diff --git a/packages/http-client-csharp/emitter/src/lib/type-converter.ts b/packages/http-client-csharp/emitter/src/lib/type-converter.ts index b2484eaffa7..269f975b972 100644 --- a/packages/http-client-csharp/emitter/src/lib/type-converter.ts +++ b/packages/http-client-csharp/emitter/src/lib/type-converter.ts @@ -11,9 +11,11 @@ import { SdkDurationType, SdkEnumType, SdkEnumValueType, - SdkHttpParameter, + SdkHeaderParameter, SdkModelPropertyType, SdkModelType, + SdkPathParameter, + SdkQueryParameter, SdkTupleType, SdkType, SdkUnionType, @@ -31,10 +33,14 @@ import { InputDurationType, InputEnumType, InputEnumValueType, + InputHeaderParameter, InputLiteralType, InputModelProperty, InputModelType, + InputPathParameter, InputPrimitiveType, + InputProperty, + InputQueryParameter, InputType, InputUnionType, } from "../type/input-type.js"; @@ -133,25 +139,24 @@ export function fromSdkModelType( ? fromSdkType(sdkContext, modelType.additionalProperties) : undefined; - const propertiesDict = new Map<SdkModelPropertyType, InputModelProperty>(); + const properties: InputProperty[] = []; for (const property of modelType.properties) { const ourProperty = fromSdkModelProperty(sdkContext, property); - if (!ourProperty) { - continue; + if (ourProperty) { + properties.push(ourProperty); } - propertiesDict.set(property, ourProperty); } inputModelType.discriminatorProperty = modelType.discriminatorProperty - ? propertiesDict.get(modelType.discriminatorProperty) + ? fromSdkModelProperty(sdkContext, modelType.discriminatorProperty) : undefined; inputModelType.baseModel = modelType.baseModel ? fromSdkModelType(sdkContext, modelType.baseModel) : undefined; - inputModelType.properties = Array.from(propertiesDict.values()).flat(); + inputModelType.properties = properties; if (modelType.discriminatedSubtypes) { const discriminatedSubtypes: Record<string, InputModelType> = {}; @@ -167,42 +172,95 @@ export function fromSdkModelType( function fromSdkModelProperty( sdkContext: CSharpEmitterContext, - property: SdkModelPropertyType, - ): InputModelProperty | undefined { - switch (property.kind) { + sdkProperty: SdkModelPropertyType, + ): InputProperty | undefined { + // TODO -- this returns undefined because some properties we do not support yet. + let property = sdkContext.__typeCache.properties.get(sdkProperty) as InputProperty | undefined; + if (property) { + return property; + } + switch (sdkProperty.kind) { case "property": - return fromSdkBodyModelProperty(sdkContext, property); + property = fromSdkBodyModelProperty(sdkContext, sdkProperty); + break; case "header": + property = fromSdkHeaderParameter(sdkContext, sdkProperty); + break; case "query": + property = fromSdkQueryParameter(sdkContext, sdkProperty); + break; case "path": - return fromSdkHttpParameterModelProperty(sdkContext, property); - default: - return undefined; + property = fromSdkPathParameter(sdkContext, sdkProperty); + break; + } + + if (property) { + sdkContext.__typeCache.updateSdkPropertyReferences(sdkProperty, property); } + + return property; } - function fromSdkHttpParameterModelProperty( + function fromSdkHeaderParameter( sdkContext: CSharpEmitterContext, - property: SdkHttpParameter, - ): InputModelProperty { - const targetType = property.type; + property: SdkHeaderParameter, + ): InputHeaderParameter { + return { + kind: property.kind, + name: property.name, + serializedName: property.serializedName, + summary: property.summary, + doc: property.doc, + type: fromSdkType(sdkContext, property.type), + optional: property.optional, + readOnly: isReadOnly(property), + decorators: property.decorators, + crossLanguageDefinitionId: property.crossLanguageDefinitionId, + collectionFormat: property.collectionFormat, + correspondingMethodParams: [], // TODO - this should be a ref of other properties + }; + } - const modelHeaderProperty: InputModelProperty = { + function fromSdkQueryParameter( + sdkContext: CSharpEmitterContext, + property: SdkQueryParameter, + ): InputQueryParameter { + return { kind: property.kind, name: property.name, serializedName: property.serializedName, summary: property.summary, doc: property.doc, - type: fromSdkType(sdkContext, targetType), + type: fromSdkType(sdkContext, property.type), optional: property.optional, readOnly: isReadOnly(property), decorators: property.decorators, crossLanguageDefinitionId: property.crossLanguageDefinitionId, - discriminator: false, - flatten: false, + correspondingMethodParams: [], // TODO - this should be a ref of other properties + explode: property.explode, }; + } - return modelHeaderProperty; + function fromSdkPathParameter( + sdkContext: CSharpEmitterContext, + property: SdkPathParameter, + ): InputPathParameter { + return { + kind: property.kind, + name: property.name, + serializedName: property.serializedName, + summary: property.summary, + doc: property.doc, + type: fromSdkType(sdkContext, property.type), + optional: property.optional, + readOnly: isReadOnly(property), + decorators: property.decorators, + crossLanguageDefinitionId: property.crossLanguageDefinitionId, + explode: property.explode, + style: property.style, + allowReserved: property.allowReserved, + correspondingMethodParams: [], // TODO - this should be a ref of other properties + }; } function fromSdkBodyModelProperty( diff --git a/packages/http-client-csharp/emitter/src/sdk-context.ts b/packages/http-client-csharp/emitter/src/sdk-context.ts index 3d4abb19fc1..d4945dbe993 100644 --- a/packages/http-client-csharp/emitter/src/sdk-context.ts +++ b/packages/http-client-csharp/emitter/src/sdk-context.ts @@ -20,8 +20,8 @@ import { InputClient, InputEnumType, InputLiteralType, - InputModelProperty, InputModelType, + InputProperty, InputType, } from "./type/input-type.js"; import { OperationResponse } from "./type/operation-response.js"; @@ -54,7 +54,7 @@ export function createCSharpEmitterContext< class SdkTypeCache { clients: Map<SdkClientType<SdkHttpOperation>, InputClient>; - properties: Map<SdkModelPropertyType, InputParameter | InputModelProperty>; + properties: Map<SdkModelPropertyType, InputParameter | InputProperty>; // TODO -- in the near future, we should replace `InputParameter` with those `InputQueryParameter`, etc. responses: Map<SdkHttpResponse, OperationResponse>; types: Map<SdkType, InputType>; models: Map<string, InputModelType>; @@ -64,7 +64,7 @@ class SdkTypeCache { constructor() { this.clients = new Map<SdkClientType<SdkHttpOperation>, InputClient>(); - this.properties = new Map<SdkModelPropertyType, InputParameter | InputModelProperty>(); + this.properties = new Map<SdkModelPropertyType, InputParameter | InputProperty>(); this.responses = new Map<SdkHttpResponse, OperationResponse>(); this.types = new Map<SdkType, InputType>(); this.models = new Map<string, InputModelType>(); @@ -80,7 +80,7 @@ class SdkTypeCache { updateSdkPropertyReferences( sdkProperty: SdkModelPropertyType, - inputProperty: InputParameter | InputModelProperty, + inputProperty: InputParameter | InputProperty, ) { this.properties.set(sdkProperty, inputProperty); this.crossLanguageDefinitionIds.set(sdkProperty.crossLanguageDefinitionId, sdkProperty.__raw); diff --git a/packages/http-client-csharp/emitter/src/type/input-type.ts b/packages/http-client-csharp/emitter/src/type/input-type.ts index 25984ef017a..990350f512b 100644 --- a/packages/http-client-csharp/emitter/src/type/input-type.ts +++ b/packages/http-client-csharp/emitter/src/type/input-type.ts @@ -3,9 +3,9 @@ import { AccessFlags, + CollectionFormat, DecoratorInfo, SdkBuiltInKinds, - SdkModelPropertyType, SerializationOptions, UsageFlags, } from "@azure-tools/typespec-client-generator-core"; @@ -121,7 +121,7 @@ export function isInputUnionType(type: InputType): type is InputUnionType { */ export interface InputModelType extends InputTypeBase { kind: "model"; - properties: InputModelProperty[]; + properties: InputProperty[]; name: string; crossLanguageDefinitionId: string; access?: AccessFlags; @@ -130,26 +130,72 @@ export interface InputModelType extends InputTypeBase { additionalProperties?: InputType; discriminatorValue?: string; discriminatedSubtypes?: Record<string, InputModelType>; - discriminatorProperty?: InputModelProperty; + discriminatorProperty?: InputProperty; baseModel?: InputModelType; serializationOptions: SerializationOptions; } -export interface InputModelProperty extends InputTypeBase { - kind: SdkModelPropertyType["kind"]; - name: string; - serializedName: string; +export interface InputPropertyTypeBase extends DecoratedType { type: InputType; + name: string; + doc?: string; + summary?: string; + // apiVersions: string[]; + // onClient: boolean; + // clientDefaultValue?: unknown; + // isApiVersionParam: boolean; optional: boolean; + crossLanguageDefinitionId: string; readOnly: boolean; + access?: AccessFlags; +} + +export interface InputModelProperty extends InputPropertyTypeBase { + kind: "property"; discriminator: boolean; - crossLanguageDefinitionId: string; + serializedName: string; + serializationOptions: SerializationOptions; flatten: boolean; - serializationOptions?: SerializationOptions; } -export function isInputModelType(type: InputType): type is InputModelType { - return type.kind === "model"; +export type InputProperty = InputModelProperty | InputHttpParameter; + +export type InputHttpParameter = + | InputQueryParameter + | InputPathParameter + | InputHeaderParameter + | InputBodyParameter; + +export interface InputQueryParameter extends InputPropertyTypeBase { + kind: "query"; + collectionFormat?: CollectionFormat; + serializedName: string; + correspondingMethodParams: InputProperty[]; + explode: boolean; +} + +export interface InputPathParameter extends InputPropertyTypeBase { + kind: "path"; + explode: boolean; + style: "simple" | "label" | "matrix" | "fragment" | "path"; + allowReserved: boolean; + serializedName: string; + correspondingMethodParams: InputProperty[]; +} + +export interface InputHeaderParameter extends InputPropertyTypeBase { + kind: "header"; + collectionFormat?: CollectionFormat; + serializedName: string; + correspondingMethodParams: InputProperty[]; +} + +export interface InputBodyParameter extends InputPropertyTypeBase { + kind: "body"; + serializedName: string; + contentTypes: string[]; + defaultContentType: string; + correspondingMethodParams: InputProperty[]; } export interface InputEnumType extends InputTypeBase { diff --git a/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts b/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts index a5012fdee56..aac23d267d2 100644 --- a/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts +++ b/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts @@ -61,7 +61,9 @@ op test(@body input: Pet): Pet; const discriminatorProperty = petModel?.properties.find( (p) => p === petModel?.discriminatorProperty, ); - strictEqual(discriminatorProperty?.name, "kind"); + ok(discriminatorProperty); + strictEqual(discriminatorProperty.kind, "property"); + strictEqual(discriminatorProperty.name, "kind"); strictEqual(discriminatorProperty.serializedName, "kind"); strictEqual(discriminatorProperty.type.kind, "string"); strictEqual(discriminatorProperty.optional, false); @@ -140,7 +142,9 @@ op test(@body input: Pet): Pet; strictEqual("kind", pet?.discriminatorProperty?.name); // assert we have a property corresponding to the discriminator property above on the base model const discriminatorProperty = pet?.properties.find((p) => p === pet?.discriminatorProperty); - strictEqual(discriminatorProperty?.name, "kind"); + ok(discriminatorProperty); + strictEqual(discriminatorProperty.kind, "property"); + strictEqual(discriminatorProperty.name, "kind"); strictEqual(discriminatorProperty.serializedName, "kind"); strictEqual(discriminatorProperty.doc, "The kind of the pet"); strictEqual(discriminatorProperty.type.kind, "enum"); @@ -232,7 +236,9 @@ op test(@body input: Pet): Pet; strictEqual("kind", pet?.discriminatorProperty?.name); // assert we have a property corresponding to the discriminator property above on the base model const discriminatorProperty = pet?.properties.find((p) => p === pet?.discriminatorProperty); - strictEqual(discriminatorProperty?.name, "kind"); + ok(discriminatorProperty); + strictEqual(discriminatorProperty.kind, "property"); + strictEqual(discriminatorProperty.name, "kind"); strictEqual(discriminatorProperty.serializedName, "kind"); strictEqual(discriminatorProperty.doc, "The kind of the pet"); strictEqual(discriminatorProperty.type.kind, "enum"); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs index a0922aa6f2d..6d92703f18b 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs @@ -1292,7 +1292,7 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithHeader", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Header), + InputFactory.HeaderParameter("foo", InputPrimitiveType.String, isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]), location: InputRequestLocation.Body, @@ -1307,7 +1307,7 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithHeader", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Header), + InputFactory.HeaderParameter("foo", InputPrimitiveType.String, isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]), location: InputRequestLocation.Body, isRequired: true)] @@ -1326,7 +1326,7 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithQuery", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Query), + InputFactory.QueryParameter("foo", InputPrimitiveType.String, isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]), location: InputRequestLocation.Body, @@ -1341,7 +1341,7 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithQuery", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Query), + InputFactory.QueryParameter("foo", InputPrimitiveType.String, isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]), location: InputRequestLocation.Body, isRequired: true)] @@ -1360,7 +1360,7 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithPathParam", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Path), + InputFactory.QueryParameter("foo", InputPrimitiveType.String, isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]), location: InputRequestLocation.Body, @@ -1375,7 +1375,7 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithPathParam", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Path), + InputFactory.QueryParameter("foo", InputPrimitiveType.String, isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]), location: InputRequestLocation.Body, isRequired: true)] @@ -1394,9 +1394,9 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithMixedParams", properties: [ - InputFactory.Property("cat", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Path), - InputFactory.Property("dog", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Query), - InputFactory.Property("bird", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Header), + InputFactory.PathParameter("cat", InputPrimitiveType.String, isRequired: true), + InputFactory.QueryParameter("dog", InputPrimitiveType.String, isRequired: true), + InputFactory.HeaderParameter("bird", InputPrimitiveType.String, isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]), location: InputRequestLocation.Body, @@ -1413,9 +1413,9 @@ public static IEnumerable<TestCaseData> TestNonBodyRequestParametersInBodyTestCa "ModelWithPathParam", properties: [ - InputFactory.Property("cat", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Path), - InputFactory.Property("dog", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Query), - InputFactory.Property("bird", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Header), + InputFactory.PathParameter("cat", InputPrimitiveType.String, isRequired: true), + InputFactory.QueryParameter("dog", InputPrimitiveType.String, isRequired: true), + InputFactory.HeaderParameter("bird", InputPrimitiveType.String, isRequired: true), ]), location: InputRequestLocation.Body, isRequired: true)] )).SetProperty("caseName", "WithMixedParametersInRequestBody"); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/JsonModelCoreTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/JsonModelCoreTests.cs index f59f2afb1de..75a75e5db18 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/JsonModelCoreTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/JsonModelCoreTests.cs @@ -113,8 +113,8 @@ public void NonBodyPropertyKindsInModel() "ModelWithNonBodyParameters", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Header), - InputFactory.Property("cat", InputPrimitiveType.String, wireName: "x-cat", isRequired: true, kind: InputModelPropertyKind.Query), + InputFactory.HeaderParameter("foo", InputPrimitiveType.String, isRequired: true), + InputFactory.QueryParameter("cat", InputPrimitiveType.String, serializedName: "x-cat", isRequired: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs index 738f6c9d1d1..dc1f66c41e7 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs @@ -765,7 +765,7 @@ public void TestIntSerializationStatement( var name = kind.ToString().ToLower(); var properties = new List<InputModelProperty> { - new InputModelProperty("requiredInt", InputModelPropertyKind.Property, "", "", new InputPrimitiveType(kind, name, $"TypeSpec.{name}", encode), true, false, false, "requiredInt", new(json: new("requiredInt"))), + new InputModelProperty("requiredInt", "", "", new InputPrimitiveType(kind, name, $"TypeSpec.{name}", encode), true, false, null, false, "requiredInt", new(json: new("requiredInt"))), }; var inputModel = new InputModelType("TestModel", "TestNamespace", "TestModel", "public", null, "", "Test model.", InputModelTypeUsage.Input, properties, null, Array.Empty<InputModelType>(), null, null, new Dictionary<string, InputModelType>(), null, false, new()); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/perf/EnumSerialization.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/perf/EnumSerialization.cs index 0ae55ee7123..31b20c2f910 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/perf/EnumSerialization.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/perf/EnumSerialization.cs @@ -20,8 +20,8 @@ public void Setup() { _resolver = new TypeSpecReferenceHandler(); _options = new JsonSerializerOptions(); - _options.Converters.Add(new TypeSpecInputEnumTypeConverter(_resolver)); - _options.Converters.Add(new TypeSpecInputEnumTypeValueConverter(_resolver)); + _options.Converters.Add(new InputEnumTypeConverter(_resolver)); + _options.Converters.Add(new InputEnumTypeValueConverter(_resolver)); } [Benchmark] @@ -40,7 +40,7 @@ public void EnumDeserialization() continue; } - _ = TypeSpecInputEnumTypeConverter.CreateEnumType(ref reader, null, null, _options!, _resolver!.CurrentResolver); + _ = InputEnumTypeConverter.CreateEnumType(ref reader, null, null, _options!, _resolver!.CurrentResolver); if (reader.TokenType == JsonTokenType.EndObject) { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ExampleMockValueBuilder.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ExampleMockValueBuilder.cs index af8795317a1..90ed2544e71 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ExampleMockValueBuilder.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/ExampleMockValueBuilder.cs @@ -207,7 +207,7 @@ private static InputExampleValue BuildModelExampleValue(InputModelType model, bo continue; // skip if this property does not have json - if (property.SerializationOptions?.Json is not { } json) + if (property is not InputModelProperty modelProperty || modelProperty.SerializationOptions?.Json is not { } json) continue; // this means a property is defined both on the base and derived type, we skip other occurrences only keep the first @@ -216,7 +216,7 @@ private static InputExampleValue BuildModelExampleValue(InputModelType model, bo continue; InputExampleValue exampleValue; - if (property.IsDiscriminator) + if (modelProperty.IsDiscriminator) { exampleValue = InputExampleValue.Value(property.Type, model.DiscriminatorValue!); } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputBodyParameter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputBodyParameter.cs new file mode 100644 index 00000000000..cf9dab5437c --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputBodyParameter.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; + +namespace Microsoft.TypeSpec.Generator.Input +{ + public class InputBodyParameter : InputProperty + { + public InputBodyParameter(string name, string? summary, string? doc, InputType type, bool isRequired, bool isReadOnly, string? access, string serializedName, IReadOnlyList<string> contentTypes, string defaultContentType) : base(name, summary, doc, type, isRequired, isReadOnly, access, serializedName) + { + Name = name; + Summary = summary; + Doc = doc; + Type = type; + IsRequired = isRequired; + IsReadOnly = isReadOnly; + SerializedName = serializedName; + ContentTypes = contentTypes; + DefaultContentType = defaultContentType; + } + + public IReadOnlyList<string> ContentTypes { get; internal set; } + public string DefaultContentType { get; internal set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputHeaderParameter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputHeaderParameter.cs new file mode 100644 index 00000000000..9d1c267301d --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputHeaderParameter.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.TypeSpec.Generator.Input +{ + public class InputHeaderParameter : InputProperty + { + public InputHeaderParameter(string name, string? summary, string? doc, InputType type, bool isRequired, bool isReadOnly, string? access, string? collectionFormat, string serializedName) : base(name, summary, doc, type, isRequired, isReadOnly, access, serializedName) + { + Name = name; + Summary = summary; + Doc = doc; + Type = type; + IsRequired = isRequired; + IsReadOnly = isReadOnly; + CollectionFormat = collectionFormat; + SerializedName = serializedName; + } + + public string? CollectionFormat { get; internal set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputLongRunningServiceMetadata.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputLongRunningServiceMetadata.cs index 29a6006bc3e..2205903c063 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputLongRunningServiceMetadata.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputLongRunningServiceMetadata.cs @@ -34,7 +34,7 @@ public InputType? ReturnType return FinalResponse.BodyType; var rawResponseType = (InputModelType)FinalResponse.BodyType; - return rawResponseType.Properties.FirstOrDefault(p => p.SerializationOptions?.Json?.Name == ResultPath)!.Type; + return rawResponseType.Properties.FirstOrDefault(p => p is InputModelProperty modelProperty && modelProperty.SerializationOptions?.Json?.Name == ResultPath)!.Type; } } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs index 4df61cb63c7..e190b3d317c 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelProperty.cs @@ -1,16 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Collections.Generic; - namespace Microsoft.TypeSpec.Generator.Input { - public class InputModelProperty + public class InputModelProperty : InputProperty { - public InputModelProperty(string name, InputModelPropertyKind kind, string? summary, string? doc, InputType type, bool isRequired, bool isReadOnly, bool isDiscriminator, string? serializedName, InputSerializationOptions serializationOptions) + public InputModelProperty(string name, string? summary, string? doc, InputType type, bool isRequired, bool isReadOnly, string? access, bool isDiscriminator, string serializedName, InputSerializationOptions serializationOptions) : base(name, summary, doc, type, isRequired, isReadOnly, access, serializedName) { Name = name; - Kind = kind; Summary = summary; Doc = doc; Type = type; @@ -18,24 +15,9 @@ public InputModelProperty(string name, InputModelPropertyKind kind, string? summ IsReadOnly = isReadOnly; IsDiscriminator = isDiscriminator; SerializationOptions = serializationOptions; - DefaultSerializedName = serializedName; } - public string Name { get; internal set; } - public InputModelPropertyKind Kind { get; internal set; } - public string? Summary { get; internal set; } - public string? Doc { get; internal set; } - public InputType Type { get; internal set; } - public bool IsRequired { get; internal set; } - public bool IsReadOnly { get; internal set; } public bool IsDiscriminator { get; internal set; } - public InputModelType? EnclosingType { get; internal set; } - public IReadOnlyList<InputDecoratorInfo> Decorators { get; internal set; } = new List<InputDecoratorInfo>(); public InputSerializationOptions? SerializationOptions { get; internal set; } - public string SerializedName => SerializationOptions?.Json?.Name ?? DefaultSerializedName ?? Name; - - // Properties that do not correspond to a body model property may not have serialization options - // but they can still have a serialized name. - internal string? DefaultSerializedName { get; set; } } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelPropertyKind.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelPropertyKind.cs deleted file mode 100644 index c6de59bc436..00000000000 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelPropertyKind.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -namespace Microsoft.TypeSpec.Generator.Input -{ - public enum InputModelPropertyKind - { - Property = 0, - Header = 1, - Query = 2, - Path = 3 - } -} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelType.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelType.cs index af64c3e8b49..194a5b954ce 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelType.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputModelType.cs @@ -11,11 +11,11 @@ namespace Microsoft.TypeSpec.Generator.Input public class InputModelType : InputType { private const string UnknownDiscriminatorValue = "unknown"; - private IReadOnlyList<InputModelProperty> _properties = []; + private IReadOnlyList<InputProperty> _properties = []; private IList<InputModelType> _derivedModels = []; // TODO: Follow up issue https://github.com/microsoft/typespec/issues/3619. After https://github.com/Azure/typespec-azure/pull/966 is completed, update this type and remove the "modelAsStruct" parameter. - public InputModelType(string name, string @namespace, string crossLanguageDefinitionId, string? access, string? deprecation, string? summary, string? doc, InputModelTypeUsage usage, IReadOnlyList<InputModelProperty> properties, InputModelType? baseModel, IReadOnlyList<InputModelType> derivedModels, string? discriminatorValue, InputModelProperty? discriminatorProperty, IReadOnlyDictionary<string, InputModelType> discriminatedSubtypes, InputType? additionalProperties, bool modelAsStruct, InputSerializationOptions serializationOptions) + public InputModelType(string name, string @namespace, string crossLanguageDefinitionId, string? access, string? deprecation, string? summary, string? doc, InputModelTypeUsage usage, IReadOnlyList<InputProperty> properties, InputModelType? baseModel, IReadOnlyList<InputModelType> derivedModels, string? discriminatorValue, InputProperty? discriminatorProperty, IReadOnlyDictionary<string, InputModelType> discriminatedSubtypes, InputType? additionalProperties, bool modelAsStruct, InputSerializationOptions serializationOptions) : base(name) { Namespace = @namespace; @@ -56,7 +56,7 @@ public InputModelType(string name, string @namespace, string crossLanguageDefini public string? Doc { get; internal set; } public InputModelTypeUsage Usage { get; internal set; } - public IReadOnlyList<InputModelProperty> Properties + public IReadOnlyList<InputProperty> Properties { get => _properties; internal set @@ -79,7 +79,7 @@ internal void AddDerivedModel(InputModelType model) _derivedModels.Add(model); } public string? DiscriminatorValue { get; internal set; } - public InputModelProperty? DiscriminatorProperty { get; internal set; } + public InputProperty? DiscriminatorProperty { get; internal set; } private Dictionary<string, InputModelType>? _discriminatedSubtypes; public IReadOnlyDictionary<string, InputModelType> DiscriminatedSubtypes { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputPathParameter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputPathParameter.cs new file mode 100644 index 00000000000..d0d28fabab8 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputPathParameter.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.TypeSpec.Generator.Input +{ + public class InputPathParameter : InputProperty + { + public InputPathParameter(string name, string? summary, string? doc, InputType type, bool isRequired, bool isReadOnly, string? access, bool allowReserved, string serializedName) : base(name, summary, doc, type, isRequired, isReadOnly, access, serializedName) + { + Name = name; + Summary = summary; + Doc = doc; + Type = type; + IsRequired = isRequired; + IsReadOnly = isReadOnly; + AllowReserved = allowReserved; + } + + public bool AllowReserved { get; internal set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputProperty.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputProperty.cs new file mode 100644 index 00000000000..70c286f1011 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputProperty.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; + +namespace Microsoft.TypeSpec.Generator.Input +{ + public abstract class InputProperty + { + protected InputProperty(string name, string? summary, string? doc, InputType type, bool isRequired, bool isReadOnly, string? access, string serializedName) + { + Name = name; + Summary = summary; + Doc = doc; + Type = type; + IsRequired = isRequired; + IsReadOnly = isReadOnly; + Access = access; + SerializedName = serializedName; + } + + public string Name { get; internal set; } + public string? Summary { get; internal set; } + public string? Doc { get; internal set; } + public InputType Type { get; internal set; } + public bool IsRequired { get; internal set; } + public bool IsReadOnly { get; internal set; } + public string? Access { get; internal set; } + public string SerializedName { get; internal set; } + public IReadOnlyList<InputDecoratorInfo> Decorators { get; internal set; } = new List<InputDecoratorInfo>(); + public InputModelType? EnclosingType { get; internal set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputQueryParameter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputQueryParameter.cs new file mode 100644 index 00000000000..1d04172008f --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/InputQueryParameter.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.TypeSpec.Generator.Input +{ + public class InputQueryParameter : InputProperty + { + public InputQueryParameter(string name, string? summary, string? doc, InputType type, bool isRequired, bool isReadOnly, string? access, string serializedName, string? collectionFormat, bool explode) : base(name, summary, doc, type, isRequired, isReadOnly, access, serializedName) + { + Name = name; + Summary = summary; + Doc = doc; + Type = type; + IsRequired = isRequired; + IsReadOnly = isReadOnly; + CollectionFormat = collectionFormat; + SerializedName = serializedName; + Explode = explode; + } + + public string? CollectionFormat { get; internal set; } + public bool Explode { get; internal set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputApiKeyAuthConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputApiKeyAuthConverter.cs similarity index 92% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputApiKeyAuthConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputApiKeyAuthConverter.cs index be95ce115e4..f70d1d160e7 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputApiKeyAuthConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputApiKeyAuthConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal class TypeSpecInputApiKeyAuthConverter : JsonConverter<InputApiKeyAuth> + internal class InputApiKeyAuthConverter : JsonConverter<InputApiKeyAuth> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputApiKeyAuthConverter(TypeSpecReferenceHandler referenceHandler) + public InputApiKeyAuthConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputArrayTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputArrayTypeConverter.cs similarity index 92% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputArrayTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputArrayTypeConverter.cs index b1547fa02dd..3d5af01efb0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputArrayTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputArrayTypeConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputArrayTypeConverter : JsonConverter<InputArrayType> + internal sealed class InputArrayTypeConverter : JsonConverter<InputArrayType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputArrayTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputArrayTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputAuthConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputAuthConverter.cs similarity index 90% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputAuthConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputAuthConverter.cs index 00e7cce0427..486eb2e40b3 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputAuthConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputAuthConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputAuthConverter : JsonConverter<InputAuth> + internal sealed class InputAuthConverter : JsonConverter<InputAuth> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputAuthConverter(TypeSpecReferenceHandler referenceHandler) + public InputAuthConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputBasicServiceMethodConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputBasicServiceMethodConverter.cs similarity index 95% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputBasicServiceMethodConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputBasicServiceMethodConverter.cs index 05d5a36e81b..adedace171d 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputBasicServiceMethodConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputBasicServiceMethodConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputBasicServiceMethodConverter : JsonConverter<InputBasicServiceMethod> + internal sealed class InputBasicServiceMethodConverter : JsonConverter<InputBasicServiceMethod> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputBasicServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) + public InputBasicServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputBodyParameterConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputBodyParameterConverter.cs new file mode 100644 index 00000000000..e1715bc4b3f --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputBodyParameterConverter.cs @@ -0,0 +1,97 @@ +// 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.TypeSpec.Generator.Input +{ + internal sealed class InputBodyParameterConverter : JsonConverter<InputBodyParameter> + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public InputBodyParameterConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputBodyParameter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.ReadReferenceAndResolve<InputBodyParameter>(_referenceHandler.CurrentResolver) ?? ReadInputBodyParameter(ref reader, null, null, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputBodyParameter value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + internal static InputBodyParameter ReadInputBodyParameter(ref Utf8JsonReader reader, string? id, string? name, JsonSerializerOptions options, ReferenceResolver resolver) + { + if (id == null) + { + reader.TryReadReferenceId(ref id); + } + + id = id ?? throw new JsonException(); + + // create an empty model property to resolve circular references + var property = new InputBodyParameter( + name: null!, + summary: null, + doc: null, + type: null!, + isRequired: false, + isReadOnly: false, + access: null, + serializedName: null!, + contentTypes: null!, + defaultContentType: null!); + resolver.AddReference(id, property); + + string? kind = null; + string? summary = null; + string? doc = null; + string? serializedName = null; + InputType? type = null; + bool isReadOnly = false; + bool isOptional = false; + string? access = null; + IReadOnlyList<string>? contentTypes = null; + string? defaultContentType = null; + IReadOnlyList<InputDecoratorInfo>? decorators = null; + + while (reader.TokenType != JsonTokenType.EndObject) + { + var isKnownProperty = reader.TryReadReferenceId(ref id) + || reader.TryReadString("name", ref name) + || reader.TryReadString("kind", ref kind) + || reader.TryReadString("summary", ref summary) + || reader.TryReadString("doc", ref doc) + || reader.TryReadComplexType("type", options, ref type) + || reader.TryReadBoolean("readOnly", ref isReadOnly) + || reader.TryReadBoolean("optional", ref isOptional) + || reader.TryReadString("access", ref access) + || reader.TryReadString("serializedName", ref serializedName) + || reader.TryReadComplexType("contentTypes",options, ref contentTypes) + || reader.TryReadComplexType("defaultContentType", options, ref defaultContentType) + || reader.TryReadComplexType("decorators", options, ref decorators); + + if (!isKnownProperty) + { + reader.SkipProperty(); + } + } + + property.Name = name ?? throw new JsonException($"{nameof(InputBodyParameter)} must have a name."); + property.Summary = summary; + property.Doc = doc; + property.Type = type ?? throw new JsonException($"{nameof(InputBodyParameter)} must have a type."); + property.IsRequired = !isOptional; + property.IsReadOnly = isReadOnly; + property.Access = access; + property.Decorators = decorators ?? []; + property.SerializedName = serializedName ?? throw new JsonException($"{nameof(InputBodyParameter)} must have a serializedName."); + property.ContentTypes = contentTypes ?? throw new JsonException($"{nameof(InputBodyParameter)} must have a contentTypes."); + property.DefaultContentType = defaultContentType ?? throw new JsonException($"{nameof(InputBodyParameter)} must have a defaultContentType."); + return property; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputClientConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputClientConverter.cs similarity index 95% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputClientConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputClientConverter.cs index 927252f40a0..dd8dd6769bd 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputClientConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputClientConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputClientConverter : JsonConverter<InputClient> + internal sealed class InputClientConverter : JsonConverter<InputClient> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputClientConverter(TypeSpecReferenceHandler referenceHandler) + public InputClientConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputConstantConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputConstantConverter.cs similarity index 96% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputConstantConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputConstantConverter.cs index 679b290ce05..99732d590ac 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputConstantConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputConstantConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal class TypeSpecInputConstantConverter : JsonConverter<InputConstant> + internal class InputConstantConverter : JsonConverter<InputConstant> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputConstantConverter(TypeSpecReferenceHandler referenceHandler) + public InputConstantConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputContinuationTokenConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputContinuationTokenConverter.cs similarity index 92% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputContinuationTokenConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputContinuationTokenConverter.cs index 0dacfbeefab..596ec1d4933 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputContinuationTokenConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputContinuationTokenConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputContinuationTokenConverter : JsonConverter<InputContinuationToken> + internal sealed class InputContinuationTokenConverter : JsonConverter<InputContinuationToken> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputContinuationTokenConverter(TypeSpecReferenceHandler referenceHandler) + public InputContinuationTokenConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDateTimeTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDateTimeTypeConverter.cs similarity index 94% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDateTimeTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDateTimeTypeConverter.cs index 6a52a62455a..3bfd93b6684 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDateTimeTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDateTimeTypeConverter.cs @@ -8,10 +8,10 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal class TypeSpecInputDateTimeTypeConverter : JsonConverter<InputDateTimeType> + internal class InputDateTimeTypeConverter : JsonConverter<InputDateTimeType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputDateTimeTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputDateTimeTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDecoratorInfoConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDecoratorInfoConverter.cs similarity index 91% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDecoratorInfoConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDecoratorInfoConverter.cs index 8a43d173b29..611f322c884 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDecoratorInfoConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDecoratorInfoConverter.cs @@ -9,11 +9,11 @@ namespace AutoRest.CSharp.Common.Input { - internal class TypeSpecInputDecoratorInfoConverter : JsonConverter<InputDecoratorInfo> + internal class InputDecoratorInfoConverter : JsonConverter<InputDecoratorInfo> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputDecoratorInfoConverter(TypeSpecReferenceHandler referenceHandler) + public InputDecoratorInfoConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDictionaryTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDictionaryTypeConverter.cs similarity index 92% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDictionaryTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDictionaryTypeConverter.cs index 808ebc52b5a..521f73cb546 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDictionaryTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDictionaryTypeConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputDictionaryTypeConverter : JsonConverter<InputDictionaryType> + internal sealed class InputDictionaryTypeConverter : JsonConverter<InputDictionaryType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputDictionaryTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputDictionaryTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDurationTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDurationTypeConverter.cs similarity index 94% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDurationTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDurationTypeConverter.cs index ec30b05afa2..a4e000aa37b 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputDurationTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputDurationTypeConverter.cs @@ -8,10 +8,10 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal class TypeSpecInputDurationTypeConverter : JsonConverter<InputDurationType> + internal class InputDurationTypeConverter : JsonConverter<InputDurationType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputDurationTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputDurationTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputEnumTypeConverter.cs similarity index 96% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputEnumTypeConverter.cs index 4ab11869c6e..fa3fc2246b3 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputEnumTypeConverter.cs @@ -9,11 +9,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputEnumTypeConverter : JsonConverter<InputEnumType> + internal sealed class InputEnumTypeConverter : JsonConverter<InputEnumType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputEnumTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputEnumTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeValueConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputEnumTypeValueConverter.cs similarity index 94% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeValueConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputEnumTypeValueConverter.cs index a584782241f..f9da615381e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputEnumTypeValueConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputEnumTypeValueConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputEnumTypeValueConverter : JsonConverter<InputEnumTypeValue> + internal sealed class InputEnumTypeValueConverter : JsonConverter<InputEnumTypeValue> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputEnumTypeValueConverter(TypeSpecReferenceHandler referenceHandler) + public InputEnumTypeValueConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputHeaderParameterConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputHeaderParameterConverter.cs new file mode 100644 index 00000000000..3bf696c962d --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputHeaderParameterConverter.cs @@ -0,0 +1,94 @@ +// 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.TypeSpec.Generator.Input +{ + internal sealed class InputHeaderParameterConverter : JsonConverter<InputHeaderParameter> + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public InputHeaderParameterConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputHeaderParameter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.ReadReferenceAndResolve<InputHeaderParameter>(_referenceHandler.CurrentResolver) ?? ReadInputHeaderParameter(ref reader, null, null, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputHeaderParameter value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + internal static InputHeaderParameter ReadInputHeaderParameter(ref Utf8JsonReader reader, string? id, string? name, JsonSerializerOptions options, ReferenceResolver resolver) + { + if (id == null) + { + reader.TryReadReferenceId(ref id); + } + + id = id ?? throw new JsonException(); + + // create an empty model property to resolve circular references + var property = new InputHeaderParameter( + name: null!, + summary: null, + doc: null, + type: null!, + isRequired: false, + isReadOnly: false, + access: null, + collectionFormat: null, + serializedName: null!); + resolver.AddReference(id, property); + + string? kind = null; + string? summary = null; + string? doc = null; + string? serializedName = null; + InputType? type = null; + bool isReadOnly = false; + bool isOptional = false; + string? access = null; + string? collectionFormat = null; + IReadOnlyList<InputDecoratorInfo>? decorators = null; + + while (reader.TokenType != JsonTokenType.EndObject) + { + var isKnownProperty = reader.TryReadReferenceId(ref id) + || reader.TryReadString("name", ref name) + || reader.TryReadString("kind", ref kind) + || reader.TryReadString("summary", ref summary) + || reader.TryReadString("doc", ref doc) + || reader.TryReadComplexType("type", options, ref type) + || reader.TryReadBoolean("readOnly", ref isReadOnly) + || reader.TryReadBoolean("optional", ref isOptional) + || reader.TryReadString("access", ref access) + || reader.TryReadString("collectionFormat", ref collectionFormat) + || reader.TryReadString("serializedName", ref serializedName) + || reader.TryReadComplexType("decorators", options, ref decorators); + + if (!isKnownProperty) + { + reader.SkipProperty(); + } + } + + property.Name = name ?? throw new JsonException($"{nameof(InputHeaderParameter)} must have a name."); + property.Summary = summary; + property.Doc = doc; + property.Type = type ?? throw new JsonException($"{nameof(InputHeaderParameter)} must have a type."); + property.IsRequired = !isOptional; + property.IsReadOnly = isReadOnly; + property.Access = access; + property.CollectionFormat = collectionFormat; + property.Decorators = decorators ?? []; + property.SerializedName = serializedName ?? throw new JsonException($"{nameof(InputHeaderParameter)} must have a serializedName."); + + return property; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputJsonSerializationOptionsConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputJsonSerializationOptionsConverter.cs similarity index 89% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputJsonSerializationOptionsConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputJsonSerializationOptionsConverter.cs index 5635820b316..84097881eb5 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputJsonSerializationOptionsConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputJsonSerializationOptionsConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputJsonSerializationOptionsConverter : JsonConverter<InputJsonSerializationOptions> + internal sealed class InputJsonSerializationOptionsConverter : JsonConverter<InputJsonSerializationOptions> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputJsonSerializationOptionsConverter(TypeSpecReferenceHandler referenceHandler) + public InputJsonSerializationOptionsConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLiteralTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLiteralTypeConverter.cs similarity index 94% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLiteralTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLiteralTypeConverter.cs index 6e01ebd94b0..7b0acaf7dd7 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLiteralTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLiteralTypeConverter.cs @@ -8,10 +8,10 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal class TypeSpecInputLiteralTypeConverter : JsonConverter<InputLiteralType> + internal class InputLiteralTypeConverter : JsonConverter<InputLiteralType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputLiteralTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputLiteralTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningPagingServiceMethodConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningPagingServiceMethodConverter.cs similarity index 95% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningPagingServiceMethodConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningPagingServiceMethodConverter.cs index fb6e3aa424c..f6f6b3326bc 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningPagingServiceMethodConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningPagingServiceMethodConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputLongRunningPagingServiceMethodConverter : JsonConverter<InputLongRunningPagingServiceMethod> + internal sealed class InputLongRunningPagingServiceMethodConverter : JsonConverter<InputLongRunningPagingServiceMethod> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputLongRunningPagingServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) + public InputLongRunningPagingServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningServiceMetadataConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningServiceMetadataConverter.cs similarity index 90% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningServiceMetadataConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningServiceMetadataConverter.cs index 7960327cc1c..968a6115d94 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningServiceMetadataConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningServiceMetadataConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputLongRunningServiceMetadataConverter : JsonConverter<InputLongRunningServiceMetadata> + internal sealed class InputLongRunningServiceMetadataConverter : JsonConverter<InputLongRunningServiceMetadata> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputLongRunningServiceMetadataConverter(TypeSpecReferenceHandler referenceHandler) + public InputLongRunningServiceMetadataConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningServiceMethodConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningServiceMethodConverter.cs similarity index 95% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningServiceMethodConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningServiceMethodConverter.cs index e17097f66ea..d5fd2f03418 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputLongRunningServiceMethodConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputLongRunningServiceMethodConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputLongRunningServiceMethodConverter : JsonConverter<InputLongRunningServiceMethod> + internal sealed class InputLongRunningServiceMethodConverter : JsonConverter<InputLongRunningServiceMethod> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputLongRunningServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) + public InputLongRunningServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputModelPropertyConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelPropertyConverter.cs similarity index 82% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputModelPropertyConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelPropertyConverter.cs index 55964641b82..83d4ad2430a 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputModelPropertyConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelPropertyConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputModelPropertyConverter : JsonConverter<InputModelProperty> + internal sealed class InputModelPropertyConverter : JsonConverter<InputModelProperty> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputModelPropertyConverter(TypeSpecReferenceHandler referenceHandler) + public InputModelPropertyConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } @@ -23,7 +23,7 @@ public override InputModelProperty Read(ref Utf8JsonReader reader, Type typeToCo public override void Write(Utf8JsonWriter writer, InputModelProperty value, JsonSerializerOptions options) => throw new NotSupportedException("Writing not supported"); - private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader reader, string? id, string? name, JsonSerializerOptions options, ReferenceResolver resolver) + internal static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader reader, string? id, string? name, JsonSerializerOptions options, ReferenceResolver resolver) { if (id == null) { @@ -35,18 +35,17 @@ private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader read // create an empty model property to resolve circular references var property = new InputModelProperty( name: null!, - kind: default, summary: null, doc: null, type: null!, isRequired: false, isReadOnly: false, + access: null, isDiscriminator: false, serializedName: null!, serializationOptions: null!); resolver.AddReference(id, property); - var isFirstProperty = true; string? kind = null; string? summary = null; string? doc = null; @@ -54,13 +53,14 @@ private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader read InputType? propertyType = null; bool isReadOnly = false; bool isOptional = false; + string? access = null; bool isDiscriminator = false; IReadOnlyList<InputDecoratorInfo>? decorators = null; InputSerializationOptions? serializationOptions = null; while (reader.TokenType != JsonTokenType.EndObject) { - var isKnownProperty = reader.TryReadReferenceId(ref isFirstProperty, ref id) + var isKnownProperty = reader.TryReadReferenceId(ref id) || reader.TryReadString("name", ref name) || reader.TryReadString("kind", ref kind) || reader.TryReadString("summary", ref summary) @@ -68,6 +68,7 @@ private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader read || reader.TryReadComplexType("type", options, ref propertyType) || reader.TryReadBoolean("readOnly", ref isReadOnly) || reader.TryReadBoolean("optional", ref isOptional) + || reader.TryReadString("access", ref access) || reader.TryReadBoolean("discriminator", ref isDiscriminator) || reader.TryReadComplexType("decorators", options, ref decorators) || reader.TryReadString("serializedName", ref serializedName) @@ -79,23 +80,17 @@ private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader read } } - if (kind == null) - { - throw new JsonException("Property must have kind"); - } - Enum.TryParse(kind, ignoreCase: true, out InputModelPropertyKind propertyKind); - property.Name = name ?? throw new JsonException($"{nameof(InputModelProperty)} must have a name."); - property.Kind = propertyKind; property.Summary = summary; property.Doc = doc; property.Type = propertyType ?? throw new JsonException($"{nameof(InputModelProperty)} must have a property type."); property.IsRequired = !isOptional; property.IsReadOnly = isReadOnly; + property.Access = access; property.IsDiscriminator = isDiscriminator; property.Decorators = decorators ?? []; property.SerializationOptions = serializationOptions; - property.DefaultSerializedName = serializedName; + property.SerializedName = serializedName ?? serializationOptions?.Json?.Name ?? name; return property; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelTypeConverter.cs similarity index 95% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelTypeConverter.cs index fff565e9a66..78e2ee1ec70 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputModelTypeConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputModelTypeConverter : JsonConverter<InputModelType> + internal sealed class InputModelTypeConverter : JsonConverter<InputModelType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputModelTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputModelTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } @@ -60,11 +60,11 @@ internal static InputModelType CreateModelType(ref Utf8JsonReader reader, string string? summary = null; string? doc = null; string? usageString = null; - InputModelProperty? discriminatorProperty = null; + InputProperty? discriminatorProperty = null; string? discriminatorValue = null; InputType? additionalProperties = null; InputModelType? baseModel = null; - IReadOnlyList<InputModelProperty>? properties = null; + IReadOnlyList<InputProperty>? properties = null; IReadOnlyDictionary<string, InputModelType>? discriminatedSubtypes = null; bool modelAsStruct = false; IReadOnlyList<InputDecoratorInfo>? decorators = null; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputNamespaceConverter.cs similarity index 93% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputNamespaceConverter.cs index af484e80fac..028e969e489 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputNamespaceConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputNamespaceConverter : JsonConverter<InputNamespace> + internal sealed class InputNamespaceConverter : JsonConverter<InputNamespace> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputNamespaceConverter(TypeSpecReferenceHandler referenceHandler) + public InputNamespaceConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputNextLinkConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputNextLinkConverter.cs similarity index 92% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputNextLinkConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputNextLinkConverter.cs index 3f393b1f196..6761e06d5da 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputNextLinkConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputNextLinkConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputNextLinkConverter : JsonConverter<InputNextLink> + internal sealed class InputNextLinkConverter : JsonConverter<InputNextLink> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputNextLinkConverter(TypeSpecReferenceHandler referenceHandler) + public InputNextLinkConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOAuth2AuthConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOAuth2AuthConverter.cs similarity index 90% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOAuth2AuthConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOAuth2AuthConverter.cs index af560c08dfc..f1dfcf69ff4 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOAuth2AuthConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOAuth2AuthConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal class TypeSpecInputOAuth2AuthConverter : JsonConverter<InputOAuth2Auth> + internal class InputOAuth2AuthConverter : JsonConverter<InputOAuth2Auth> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputOAuth2AuthConverter(TypeSpecReferenceHandler referenceHandler) + public InputOAuth2AuthConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationConverter.cs similarity index 96% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationConverter.cs index c4a1af171ad..2a31e85953f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputOperationConverter : JsonConverter<InputOperation> + internal sealed class InputOperationConverter : JsonConverter<InputOperation> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputOperationConverter(TypeSpecReferenceHandler referenceHandler) + public InputOperationConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationResponseConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationResponseConverter.cs similarity index 92% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationResponseConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationResponseConverter.cs index efd96d0cdf5..5c291110e82 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationResponseConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationResponseConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputOperationResponseConverter : JsonConverter<InputOperationResponse> + internal sealed class InputOperationResponseConverter : JsonConverter<InputOperationResponse> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputOperationResponseConverter(TypeSpecReferenceHandler referenceHandler) + public InputOperationResponseConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationResponseHeaderConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationResponseHeaderConverter.cs similarity index 91% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationResponseHeaderConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationResponseHeaderConverter.cs index eb98746efe5..5a9084f83ce 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputOperationResponseHeaderConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputOperationResponseHeaderConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputOperationResponseHeaderConverter : JsonConverter<InputOperationResponseHeader> + internal sealed class InputOperationResponseHeaderConverter : JsonConverter<InputOperationResponseHeader> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputOperationResponseHeaderConverter(TypeSpecReferenceHandler referenceHandler) + public InputOperationResponseHeaderConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPagingServiceMetadataConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPagingServiceMetadataConverter.cs similarity index 91% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPagingServiceMetadataConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPagingServiceMetadataConverter.cs index 6f236406221..3bdffca1822 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPagingServiceMetadataConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPagingServiceMetadataConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputPagingServiceMetadataConverter : JsonConverter<InputPagingServiceMetadata> + internal sealed class InputPagingServiceMetadataConverter : JsonConverter<InputPagingServiceMetadata> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputPagingServiceMetadataConverter(TypeSpecReferenceHandler referenceHandler) + public InputPagingServiceMetadataConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPagingServiceMethodConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPagingServiceMethodConverter.cs similarity index 95% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPagingServiceMethodConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPagingServiceMethodConverter.cs index b40ea874bef..198e420c16c 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPagingServiceMethodConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPagingServiceMethodConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputPagingServiceMethodConverter : JsonConverter<InputPagingServiceMethod> + internal sealed class InputPagingServiceMethodConverter : JsonConverter<InputPagingServiceMethod> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputPagingServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) + public InputPagingServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputParameterConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputParameterConverter.cs similarity index 96% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputParameterConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputParameterConverter.cs index 4ed63c5b889..8d76c47d7c1 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputParameterConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputParameterConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputParameterConverter : JsonConverter<InputParameter> + internal sealed class InputParameterConverter : JsonConverter<InputParameter> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputParameterConverter(TypeSpecReferenceHandler referenceHandler) + public InputParameterConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPathParameterConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPathParameterConverter.cs new file mode 100644 index 00000000000..061339b3c2d --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPathParameterConverter.cs @@ -0,0 +1,93 @@ +// 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.TypeSpec.Generator.Input +{ + internal sealed class InputPathParameterConverter : JsonConverter<InputPathParameter> + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public InputPathParameterConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputPathParameter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.ReadReferenceAndResolve<InputPathParameter>(_referenceHandler.CurrentResolver) ?? ReadInputPathParameter(ref reader, null, null, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputPathParameter value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + internal static InputPathParameter ReadInputPathParameter(ref Utf8JsonReader reader, string? id, string? name, JsonSerializerOptions options, ReferenceResolver resolver) + { + if (id == null) + { + reader.TryReadReferenceId(ref id); + } + + id = id ?? throw new JsonException(); + + // create an empty model property to resolve circular references + var property = new InputPathParameter( + name: null!, + summary: null, + doc: null, + type: null!, + isRequired: false, + isReadOnly: false, + access: null, + allowReserved: false, + serializedName: null!); + resolver.AddReference(id, property); + + string? kind = null; + string? summary = null; + string? doc = null; + string? serializedName = null; + InputType? type = null; + bool isReadOnly = false; + bool isOptional = false; + string? access = null; + bool allowReserved = false; + IReadOnlyList<InputDecoratorInfo>? decorators = null; + + while (reader.TokenType != JsonTokenType.EndObject) + { + var isKnownProperty = reader.TryReadReferenceId(ref id) + || reader.TryReadString("name", ref name) + || reader.TryReadString("kind", ref kind) + || reader.TryReadString("summary", ref summary) + || reader.TryReadString("doc", ref doc) + || reader.TryReadComplexType("type", options, ref type) + || reader.TryReadBoolean("readOnly", ref isReadOnly) + || reader.TryReadBoolean("optional", ref isOptional) + || reader.TryReadString("access", ref access) + || reader.TryReadBoolean("allowReserved", ref allowReserved) + || reader.TryReadString("serializedName", ref serializedName) + || reader.TryReadComplexType("decorators", options, ref decorators); + + if (!isKnownProperty) + { + reader.SkipProperty(); + } + } + + property.Name = name ?? throw new JsonException($"{nameof(InputPathParameter)} must have a name."); + property.Summary = summary; + property.Doc = doc; + property.Type = type ?? throw new JsonException($"{nameof(InputPathParameter)} must have a type."); + property.IsRequired = !isOptional; + property.IsReadOnly = isReadOnly; + property.Access = access; + property.AllowReserved = allowReserved; + property.Decorators = decorators ?? []; + property.SerializedName = serializedName ?? throw new JsonException($"{nameof(InputPathParameter)} must have a serializedName."); + return property; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPrimitiveTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPrimitiveTypeConverter.cs similarity index 93% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPrimitiveTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPrimitiveTypeConverter.cs index f5ee226e7bd..a74af259e4f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputPrimitiveTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPrimitiveTypeConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputPrimitiveTypeConverter : JsonConverter<InputPrimitiveType> + internal sealed class InputPrimitiveTypeConverter : JsonConverter<InputPrimitiveType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputPrimitiveTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputPrimitiveTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPropertyConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPropertyConverter.cs new file mode 100644 index 00000000000..846b5975514 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputPropertyConverter.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.TypeSpec.Generator.Input +{ + internal sealed class InputPropertyConverter : JsonConverter<InputProperty> + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public InputPropertyConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputProperty Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.ReadReferenceAndResolve<InputProperty>(_referenceHandler.CurrentResolver) ?? ReadInputProperty(ref reader, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputProperty value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + private static InputProperty ReadInputProperty(ref Utf8JsonReader reader, JsonSerializerOptions options, ReferenceResolver resolver) + { + string? id = null; + string? kind = null; + + InputProperty? property = null; + while (reader.TokenType != JsonTokenType.EndObject) + { + var isIdOrKind = reader.TryReadReferenceId(ref id) + || reader.TryReadString("kind", ref kind); + if (isIdOrKind) + { + continue; + } + property = CreatePropertyType(ref reader, id, kind, options, resolver); + } + + return property ?? CreatePropertyType(ref reader, id, kind, options, resolver); + } + + private static InputProperty CreatePropertyType(ref Utf8JsonReader reader, string? id, string? kind, JsonSerializerOptions options, ReferenceResolver resolver) => kind switch + { + null => throw new JsonException($"InputProperty (id: '{id}') must have a 'Kind' property"), + ModelPropertyKind => InputModelPropertyConverter.ReadInputModelProperty(ref reader, id, kind, options, resolver), + HeaderParameterKind => InputHeaderParameterConverter.ReadInputHeaderParameter(ref reader, id, kind, options, resolver), + QueryParameterKind => InputQueryParameterConverter.ReadInputQueryParameter(ref reader, id, kind, options, resolver), + PathParameterKind => InputPathParameterConverter.ReadInputPathParameter(ref reader, id, kind, options, resolver), + BodyParameterKind => InputBodyParameterConverter.ReadInputBodyParameter(ref reader, id, kind, options, resolver), + _ => throw new JsonException($"Unknown kind for InputProperty (id: '{id}'): '{kind}'"), + }; + + private const string ModelPropertyKind = "property"; + private const string HeaderParameterKind = "header"; + private const string QueryParameterKind = "query"; + private const string PathParameterKind = "path"; + private const string BodyParameterKind = "body"; + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputQueryParameterConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputQueryParameterConverter.cs new file mode 100644 index 00000000000..9ae318a8249 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputQueryParameterConverter.cs @@ -0,0 +1,97 @@ +// 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.TypeSpec.Generator.Input +{ + internal sealed class InputQueryParameterConverter : JsonConverter<InputQueryParameter> + { + private readonly TypeSpecReferenceHandler _referenceHandler; + + public InputQueryParameterConverter(TypeSpecReferenceHandler referenceHandler) + { + _referenceHandler = referenceHandler; + } + + public override InputQueryParameter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.ReadReferenceAndResolve<InputQueryParameter>(_referenceHandler.CurrentResolver) ?? ReadInputQueryParameter(ref reader, null, null, options, _referenceHandler.CurrentResolver); + + public override void Write(Utf8JsonWriter writer, InputQueryParameter value, JsonSerializerOptions options) + => throw new NotSupportedException("Writing not supported"); + + internal static InputQueryParameter ReadInputQueryParameter(ref Utf8JsonReader reader, string? id, string? name, JsonSerializerOptions options, ReferenceResolver resolver) + { + if (id == null) + { + reader.TryReadReferenceId(ref id); + } + + id = id ?? throw new JsonException(); + + // create an empty model property to resolve circular references + var property = new InputQueryParameter( + name: null!, + summary: null, + doc: null, + type: null!, + isRequired: false, + isReadOnly: false, + access: null, + serializedName: null!, + collectionFormat: null, + explode: false); + resolver.AddReference(id, property); + + string? kind = null; + string? summary = null; + string? doc = null; + string? serializedName = null; + InputType? type = null; + bool isReadOnly = false; + bool isOptional = false; + string? access = null; + string? collectionFormat = null; + bool explode = false; + IReadOnlyList<InputDecoratorInfo>? decorators = null; + + while (reader.TokenType != JsonTokenType.EndObject) + { + var isKnownProperty = reader.TryReadReferenceId(ref id) + || reader.TryReadString("name", ref name) + || reader.TryReadString("kind", ref kind) + || reader.TryReadString("summary", ref summary) + || reader.TryReadString("doc", ref doc) + || reader.TryReadComplexType("type", options, ref type) + || reader.TryReadBoolean("readOnly", ref isReadOnly) + || reader.TryReadBoolean("optional", ref isOptional) + || reader.TryReadString("access", ref access) + || reader.TryReadString("collectionFormat", ref collectionFormat) + || reader.TryReadString("serializedName", ref serializedName) + || reader.TryReadBoolean("explode", ref explode) + || reader.TryReadComplexType("decorators", options, ref decorators); + + if (!isKnownProperty) + { + reader.SkipProperty(); + } + } + + property.Name = name ?? throw new JsonException($"{nameof(InputQueryParameter)} must have a name."); + property.Summary = summary; + property.Doc = doc; + property.Type = type ?? throw new JsonException($"{nameof(InputQueryParameter)} must have a type."); + property.IsRequired = !isOptional; + property.IsReadOnly = isReadOnly; + property.Access = access; + property.CollectionFormat = collectionFormat; + property.Explode = explode; + property.Decorators = decorators ?? []; + property.SerializedName = serializedName ?? throw new JsonException($"{nameof(InputQueryParameter)} must have a serializedName."); + return property; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputSerializationOptionsConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputSerializationOptionsConverter.cs similarity index 91% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputSerializationOptionsConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputSerializationOptionsConverter.cs index a9d6a7b9299..2d6ab0bed2f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputSerializationOptionsConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputSerializationOptionsConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputSerializationOptionsConverter : JsonConverter<InputSerializationOptions> + internal sealed class InputSerializationOptionsConverter : JsonConverter<InputSerializationOptions> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputSerializationOptionsConverter(TypeSpecReferenceHandler referenceHandler) + public InputSerializationOptionsConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputServiceMethodConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputServiceMethodConverter.cs similarity index 70% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputServiceMethodConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputServiceMethodConverter.cs index 68f236c0c8a..f58f26d7850 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputServiceMethodConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputServiceMethodConverter.cs @@ -7,7 +7,7 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputServiceMethodConverter : JsonConverter<InputServiceMethod> + internal sealed class InputServiceMethodConverter : JsonConverter<InputServiceMethod> { private readonly TypeSpecReferenceHandler _referenceHandler; private const string BasicKind = "basic"; @@ -15,7 +15,7 @@ internal sealed class TypeSpecInputServiceMethodConverter : JsonConverter<InputS private const string LongRunningKind = "lro"; private const string LongRunningPagingKind = "lropaging"; - public TypeSpecInputServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) + public InputServiceMethodConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } @@ -52,11 +52,11 @@ private InputServiceMethod CreateInputServiceMethod(ref Utf8JsonReader reader, J private InputServiceMethod CreateDerivedType(ref Utf8JsonReader reader, string? id, string? kind, string? name, JsonSerializerOptions options) => kind switch { null => throw new JsonException($"InputType (id: '{id}', name: '{name}') must have a 'Kind' property"), - BasicKind => TypeSpecInputBasicServiceMethodConverter.CreateInputBasicServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), - PagingKind => TypeSpecInputPagingServiceMethodConverter.CreateInputPagingServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), - LongRunningKind => TypeSpecInputLongRunningServiceMethodConverter.CreateInputLongRunningServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), - LongRunningPagingKind => TypeSpecInputLongRunningPagingServiceMethodConverter.CreateInputLongRunningPagingServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), - _ => TypeSpecInputBasicServiceMethodConverter.CreateInputBasicServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), + BasicKind => InputBasicServiceMethodConverter.CreateInputBasicServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), + PagingKind => InputPagingServiceMethodConverter.CreateInputPagingServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), + LongRunningKind => InputLongRunningServiceMethodConverter.CreateInputLongRunningServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), + LongRunningPagingKind => InputLongRunningPagingServiceMethodConverter.CreateInputLongRunningPagingServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), + _ => InputBasicServiceMethodConverter.CreateInputBasicServiceMethod(ref reader, id, name, options, _referenceHandler.CurrentResolver), }; } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputServiceMethodResponseConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputServiceMethodResponseConverter.cs similarity index 90% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputServiceMethodResponseConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputServiceMethodResponseConverter.cs index 49e4f207cba..83261ab55a9 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputServiceMethodResponseConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputServiceMethodResponseConverter.cs @@ -8,11 +8,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputServiceMethodResponseConverter : JsonConverter<InputServiceMethodResponse> + internal sealed class InputServiceMethodResponseConverter : JsonConverter<InputServiceMethodResponse> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputServiceMethodResponseConverter (TypeSpecReferenceHandler referenceHandler) + public InputServiceMethodResponseConverter (TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputTypeConverter.cs similarity index 63% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputTypeConverter.cs index 72c5dce58ec..c664d1a6764 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputTypeConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputTypeConverter : JsonConverter<InputType> + internal sealed class InputTypeConverter : JsonConverter<InputType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } @@ -62,17 +62,17 @@ private InputType CreateInputType(ref Utf8JsonReader reader, JsonSerializerOptio private InputType CreateDerivedType(ref Utf8JsonReader reader, string? id, string? kind, string? name, JsonSerializerOptions options) => kind switch { null => throw new JsonException($"InputType (id: '{id}', name: '{name}') must have a 'Kind' property"), - LiteralKind => TypeSpecInputLiteralTypeConverter.CreateInputLiteralType(ref reader, id, name, options, _referenceHandler.CurrentResolver), - UnionKind => TypeSpecInputUnionTypeConverter.CreateInputUnionType(ref reader, id, name, options, _referenceHandler.CurrentResolver), - ModelKind => TypeSpecInputModelTypeConverter.CreateModelType(ref reader, id, name, options, _referenceHandler.CurrentResolver), - EnumKind => TypeSpecInputEnumTypeConverter.CreateEnumType(ref reader, id, name, options, _referenceHandler.CurrentResolver), - EnumValueKind => TypeSpecInputEnumTypeValueConverter.CreateEnumTypeValue(ref reader, id, name, options, _referenceHandler.CurrentResolver), - ArrayKind => TypeSpecInputArrayTypeConverter.CreateListType(ref reader, id, name, options, _referenceHandler.CurrentResolver), - DictionaryKind => TypeSpecInputDictionaryTypeConverter.CreateDictionaryType(ref reader, id, options, _referenceHandler.CurrentResolver), - UtcDateTimeKind or OffsetDateTimeKind => TypeSpecInputDateTimeTypeConverter.CreateDateTimeType(ref reader, id, name, options, _referenceHandler.CurrentResolver), - DurationKind => TypeSpecInputDurationTypeConverter.CreateDurationType(ref reader, id, name, options, _referenceHandler.CurrentResolver), + LiteralKind => InputLiteralTypeConverter.CreateInputLiteralType(ref reader, id, name, options, _referenceHandler.CurrentResolver), + UnionKind => InputUnionTypeConverter.CreateInputUnionType(ref reader, id, name, options, _referenceHandler.CurrentResolver), + ModelKind => InputModelTypeConverter.CreateModelType(ref reader, id, name, options, _referenceHandler.CurrentResolver), + EnumKind => InputEnumTypeConverter.CreateEnumType(ref reader, id, name, options, _referenceHandler.CurrentResolver), + EnumValueKind => InputEnumTypeValueConverter.CreateEnumTypeValue(ref reader, id, name, options, _referenceHandler.CurrentResolver), + ArrayKind => InputArrayTypeConverter.CreateListType(ref reader, id, name, options, _referenceHandler.CurrentResolver), + DictionaryKind => InputDictionaryTypeConverter.CreateDictionaryType(ref reader, id, options, _referenceHandler.CurrentResolver), + UtcDateTimeKind or OffsetDateTimeKind => InputDateTimeTypeConverter.CreateDateTimeType(ref reader, id, name, options, _referenceHandler.CurrentResolver), + DurationKind => InputDurationTypeConverter.CreateDurationType(ref reader, id, name, options, _referenceHandler.CurrentResolver), NullableKind => TypeSpecInputNullableTypeConverter.CreateNullableType(ref reader, id, name, options, _referenceHandler.CurrentResolver), - _ => TypeSpecInputPrimitiveTypeConverter.CreatePrimitiveType(ref reader, id, kind, name, options, _referenceHandler.CurrentResolver), + _ => InputPrimitiveTypeConverter.CreatePrimitiveType(ref reader, id, kind, name, options, _referenceHandler.CurrentResolver), }; } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputUnionTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputUnionTypeConverter.cs similarity index 93% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputUnionTypeConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputUnionTypeConverter.cs index 98ae8b66cdb..b286b20d6bd 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputUnionTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputUnionTypeConverter.cs @@ -8,10 +8,10 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal class TypeSpecInputUnionTypeConverter : JsonConverter<InputUnionType> + internal class InputUnionTypeConverter : JsonConverter<InputUnionType> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputUnionTypeConverter(TypeSpecReferenceHandler referenceHandler) + public InputUnionTypeConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputXmlNamespaceOptionsConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputXmlNamespaceOptionsConverter.cs similarity index 90% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputXmlNamespaceOptionsConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputXmlNamespaceOptionsConverter.cs index 467a77753f0..6ddec231e23 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputXmlNamespaceOptionsConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputXmlNamespaceOptionsConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputXmlNamespaceOptionsConverter : JsonConverter<InputXmlNamespaceOptions> + internal sealed class InputXmlNamespaceOptionsConverter : JsonConverter<InputXmlNamespaceOptions> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputXmlNamespaceOptionsConverter(TypeSpecReferenceHandler referenceHandler) + public InputXmlNamespaceOptionsConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputXmlSerializationOptionsConverter.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputXmlSerializationOptionsConverter.cs similarity index 92% rename from packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputXmlSerializationOptionsConverter.cs rename to packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputXmlSerializationOptionsConverter.cs index 66a8e58707f..e27a14777fd 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecInputXmlSerializationOptionsConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/InputXmlSerializationOptionsConverter.cs @@ -7,11 +7,11 @@ namespace Microsoft.TypeSpec.Generator.Input { - internal sealed class TypeSpecInputXmlSerializationOptionsConverter : JsonConverter<InputXmlSerializationOptions> + internal sealed class InputXmlSerializationOptionsConverter : JsonConverter<InputXmlSerializationOptions> { private readonly TypeSpecReferenceHandler _referenceHandler; - public TypeSpecInputXmlSerializationOptionsConverter(TypeSpecReferenceHandler referenceHandler) + public InputXmlSerializationOptionsConverter(TypeSpecReferenceHandler referenceHandler) { _referenceHandler = referenceHandler; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs index f64522d2d1d..33e7421417f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputTypes/Serialization/TypeSpecSerialization.cs @@ -22,44 +22,49 @@ public static class TypeSpecSerialization AllowTrailingCommas = true, Converters = { - new TypeSpecInputNamespaceConverter(referenceHandler), + new InputNamespaceConverter(referenceHandler), new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), - new TypeSpecInputTypeConverter(referenceHandler), - new TypeSpecInputArrayTypeConverter(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 TypeSpecInputNextLinkConverter(referenceHandler), - new TypeSpecInputContinuationTokenConverter(referenceHandler), - new TypeSpecInputParameterConverter(referenceHandler), - new TypeSpecInputPrimitiveTypeConverter(referenceHandler), - new TypeSpecInputOperationResponseConverter(referenceHandler), - new TypeSpecInputOperationResponseHeaderConverter(referenceHandler), - new TypeSpecInputDateTimeTypeConverter(referenceHandler), - new TypeSpecInputDurationTypeConverter(referenceHandler), - new TypeSpecInputAuthConverter(referenceHandler), - new TypeSpecInputApiKeyAuthConverter(referenceHandler), - new TypeSpecInputOAuth2AuthConverter(referenceHandler), - new TypeSpecInputDecoratorInfoConverter(referenceHandler), - new TypeSpecInputSerializationOptionsConverter(referenceHandler), - new TypeSpecInputJsonSerializationOptionsConverter(referenceHandler), - new TypeSpecInputXmlSerializationOptionsConverter(referenceHandler), - new TypeSpecInputXmlNamespaceOptionsConverter(referenceHandler), - new TypeSpecInputServiceMethodConverter(referenceHandler), - new TypeSpecInputBasicServiceMethodConverter(referenceHandler), - new TypeSpecInputPagingServiceMethodConverter(referenceHandler), - new TypeSpecInputPagingServiceMetadataConverter(referenceHandler), - new TypeSpecInputLongRunningServiceMethodConverter(referenceHandler), - new TypeSpecInputLongRunningServiceMetadataConverter(referenceHandler), - new TypeSpecInputLongRunningPagingServiceMethodConverter(referenceHandler), - new TypeSpecInputServiceMethodResponseConverter(referenceHandler), + new InputTypeConverter(referenceHandler), + new InputArrayTypeConverter(referenceHandler), + new InputDictionaryTypeConverter(referenceHandler), + new InputEnumTypeConverter(referenceHandler), + new InputEnumTypeValueConverter(referenceHandler), + new InputModelTypeConverter(referenceHandler), + new InputModelPropertyConverter(referenceHandler), + new InputConstantConverter(referenceHandler), + new InputLiteralTypeConverter(referenceHandler), + new InputUnionTypeConverter(referenceHandler), + new InputClientConverter(referenceHandler), + new InputOperationConverter(referenceHandler), + new InputNextLinkConverter(referenceHandler), + new InputContinuationTokenConverter(referenceHandler), + new InputParameterConverter(referenceHandler), + new InputPrimitiveTypeConverter(referenceHandler), + new InputOperationResponseConverter(referenceHandler), + new InputOperationResponseHeaderConverter(referenceHandler), + new InputDateTimeTypeConverter(referenceHandler), + new InputDurationTypeConverter(referenceHandler), + new InputAuthConverter(referenceHandler), + new InputApiKeyAuthConverter(referenceHandler), + new InputOAuth2AuthConverter(referenceHandler), + new InputDecoratorInfoConverter(referenceHandler), + new InputSerializationOptionsConverter(referenceHandler), + new InputJsonSerializationOptionsConverter(referenceHandler), + new InputXmlSerializationOptionsConverter(referenceHandler), + new InputXmlNamespaceOptionsConverter(referenceHandler), + new InputServiceMethodConverter(referenceHandler), + new InputBasicServiceMethodConverter(referenceHandler), + new InputPagingServiceMethodConverter(referenceHandler), + new InputPagingServiceMetadataConverter(referenceHandler), + new InputLongRunningServiceMethodConverter(referenceHandler), + new InputLongRunningServiceMetadataConverter(referenceHandler), + new InputLongRunningPagingServiceMethodConverter(referenceHandler), + new InputServiceMethodResponseConverter(referenceHandler), + new InputPropertyConverter(referenceHandler), + new InputHeaderParameterConverter(referenceHandler), + new InputQueryParameterConverter(referenceHandler), + new InputPathParameterConverter(referenceHandler), + new InputBodyParameterConverter(referenceHandler), } }; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/perf/CodeWriterBenchmark.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/perf/CodeWriterBenchmark.cs index 5ac5d7f02f3..2d6fb354bc1 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/perf/CodeWriterBenchmark.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/perf/CodeWriterBenchmark.cs @@ -19,7 +19,7 @@ public CodeWriterBenchmark() GeneratorInitializer.Initialize(); var properties = new[] { - new InputModelProperty("MyProperty", InputModelPropertyKind.Property, null, "The property of mine", InputPrimitiveType.Int32, true, false, false, "myProperty", new(json: new("myProperty"))) + new InputModelProperty("MyProperty", null, "The property of mine", InputPrimitiveType.Int32, true, false, null, false, "myProperty", new(json: new("myProperty"))) }; var inputModel = new InputModelType("MyModel", "MyNamespace", string.Empty, null, null, null, "Test model", InputModelTypeUsage.Input | InputModelTypeUsage.Output, properties, null, Array.Empty<InputModelType>(), null, null, new Dictionary<string, InputModelType>(), null, false, new()); var modelProvider = new ModelProvider(inputModel); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/LibraryVisitor.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/LibraryVisitor.cs index c41322484bc..f605aedbc49 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/LibraryVisitor.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/LibraryVisitor.cs @@ -125,7 +125,7 @@ protected internal virtual void VisitLibrary(OutputLibrary library) /// <param name="property">The original input model property.</param> /// <param name="propertyProvider">The current conversion.</param> /// <returns>Null if it should be removed otherwise the modified version of the <see cref="PropertyProvider"/>.</returns> - protected internal virtual PropertyProvider? PreVisitProperty(InputModelProperty property, PropertyProvider? propertyProvider) + protected internal virtual PropertyProvider? PreVisitProperty(InputProperty property, PropertyProvider? propertyProvider) { return propertyProvider; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs index 02acf2c4284..cb888a1c6ae 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs @@ -26,25 +26,25 @@ public PropertyWireInformation(SerializationFormat serializationFormat, bool isR /// <summary> /// Initializes a new instance of the <see cref="PropertyWireInformation"/> class. /// </summary> - /// <param name="inputModelProperty">The input model property.</param> - internal PropertyWireInformation(InputModelProperty inputModelProperty) - : base(CodeModelGenerator.Instance.TypeFactory.GetSerializationFormat(inputModelProperty.Type), inputModelProperty.SerializedName) + /// <param name="inputProperty">The input model property.</param> + internal PropertyWireInformation(InputProperty inputProperty) + : base(CodeModelGenerator.Instance.TypeFactory.GetSerializationFormat(inputProperty.Type), inputProperty.SerializedName) // TODO -- this is only temporary because we do not support other type of serialization, improvement tracking https://github.com/microsoft/typespec/issues/5861 { - IsRequired = inputModelProperty.IsRequired; - IsReadOnly = inputModelProperty.IsReadOnly; - IsNullable = inputModelProperty.Type is InputNullableType; - IsDiscriminator = inputModelProperty.IsDiscriminator; - Location = ToPropertyLocation(inputModelProperty.Kind); + IsRequired = inputProperty.IsRequired; + IsReadOnly = inputProperty.IsReadOnly; + IsNullable = inputProperty.Type is InputNullableType; + IsDiscriminator = inputProperty is InputModelProperty modelProperty && modelProperty.IsDiscriminator; + Location = ToPropertyLocation(inputProperty); } - private static PropertyLocation ToPropertyLocation(InputModelPropertyKind kind) - => kind switch + private static PropertyLocation ToPropertyLocation(InputProperty inputProperty) + => inputProperty switch { - InputModelPropertyKind.Header => PropertyLocation.Header, - InputModelPropertyKind.Property => PropertyLocation.Body, - InputModelPropertyKind.Query => PropertyLocation.Query, - InputModelPropertyKind.Path => PropertyLocation.Path, + InputHeaderParameter => PropertyLocation.Header, + InputModelProperty => PropertyLocation.Body, + InputQueryParameter => PropertyLocation.Query, + InputPathParameter => PropertyLocation.Path, _ => PropertyLocation.Unknown, }; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs index 8044f70da2b..1d4e654d654 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs @@ -14,7 +14,7 @@ namespace Microsoft.TypeSpec.Generator.Providers internal class CanonicalTypeProvider : TypeProvider { private readonly TypeProvider _generatedTypeProvider; - private readonly Dictionary<string, InputModelProperty> _specPropertiesMap; + private readonly Dictionary<string, InputProperty> _specPropertiesMap; private readonly Dictionary<string, string?> _serializedNameMap; private readonly HashSet<string> _renamedProperties; private readonly HashSet<string> _renamedFields; @@ -70,13 +70,13 @@ protected override PropertyProvider[] BuildProperties() foreach (var customProperty in customProperties) { - InputModelProperty? specProperty = null; + InputProperty? specProperty = null; if (TryGetCandidateSpecProperty(customProperty, out var candidateSpecProperty)) { specProperty = candidateSpecProperty; - customProperty.IsDiscriminator = specProperty.IsDiscriminator; customProperty.WireInfo = new PropertyWireInformation(specProperty); + customProperty.IsDiscriminator = customProperty.WireInfo.IsDiscriminator; } string? serializedName = specProperty?.SerializedName; @@ -132,7 +132,7 @@ protected override FieldProvider[] BuildFields() foreach (var customField in customFields) { - InputModelProperty? specProperty = null; + InputProperty? specProperty = null; if (TryGetCandidateSpecProperty(customField, out var candidateSpecProperty)) { @@ -178,7 +178,7 @@ protected override FieldProvider[] BuildFields() } private static bool IsCustomizedEnumProperty( - InputModelProperty? inputProperty, + InputProperty? inputProperty, CSharpType customType, [NotNullWhen(true)] out InputType? specValueType) { @@ -197,7 +197,7 @@ private static bool IsCustomizedEnumProperty( return false; } - private static CSharpType EnsureCorrectTypeRepresentation(InputModelProperty? specProperty, CSharpType customType) + private static CSharpType EnsureCorrectTypeRepresentation(InputProperty? specProperty, CSharpType customType) { if (customType.IsCollection) { @@ -218,7 +218,7 @@ private static CSharpType EnsureCorrectTypeRepresentation(InputModelProperty? sp return EnsureLiteral(specProperty, customType); } - private static CSharpType EnsureLiteral(InputModelProperty? specProperty, CSharpType customType) + private static CSharpType EnsureLiteral(InputProperty? specProperty, CSharpType customType) { if (specProperty?.Type is InputLiteralType inputLiteral && (customType.IsFrameworkType || customType.IsEnum)) { @@ -228,7 +228,7 @@ private static CSharpType EnsureLiteral(InputModelProperty? specProperty, CSharp return customType; } - private static CSharpType EnsureEnum(InputModelProperty? specProperty, CSharpType customType) + private static CSharpType EnsureEnum(InputProperty? specProperty, CSharpType customType) { if (!customType.IsFrameworkType && IsCustomizedEnumProperty(specProperty, customType, out var specType)) { @@ -266,7 +266,7 @@ private static CSharpType EnsureEnum(InputModelProperty? specProperty, CSharpTyp private bool TryGetCandidateSpecProperty( PropertyProvider customProperty, - [NotNullWhen(true)] out InputModelProperty? candidateSpecProperty) + [NotNullWhen(true)] out InputProperty? candidateSpecProperty) { if (customProperty.OriginalName != null && _specPropertiesMap.TryGetValue(customProperty.OriginalName, out candidateSpecProperty)) { @@ -284,7 +284,7 @@ private bool TryGetCandidateSpecProperty( return false; } - private bool TryGetCandidateSpecProperty(FieldProvider customField, [NotNullWhen(true)] out InputModelProperty? candidateSpecProperty) + private bool TryGetCandidateSpecProperty(FieldProvider customField, [NotNullWhen(true)] out InputProperty? candidateSpecProperty) { if (customField.OriginalName != null && _specPropertiesMap.TryGetValue(customField.OriginalName, out candidateSpecProperty)) { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index a93c96c0278..1b0350d9e49 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -208,7 +208,7 @@ protected override FieldProvider[] BuildFields() foreach (var property in _inputModel.Properties) { - if (property.IsDiscriminator) + if (IsDiscriminator(property)) continue; var derivedProperty = InputDerivedProperties.FirstOrDefault(p => p.Value.ContainsKey(property.Name)).Value?[property.Name]; @@ -227,6 +227,11 @@ protected override FieldProvider[] BuildFields() return [.. fields]; } + private static bool IsDiscriminator(InputProperty property) + { + return property is InputModelProperty modelProperty && modelProperty.IsDiscriminator; + } + private List<FieldProvider> BuildAdditionalPropertyFields() { var fields = new List<FieldProvider>(); @@ -344,12 +349,12 @@ private List<PropertyProvider> BuildAdditionalPropertyProperties() return properties; } - private Dictionary<InputModelType, Dictionary<string, InputModelProperty>>? _inputDerivedProperties; - private Dictionary<InputModelType, Dictionary<string, InputModelProperty>> InputDerivedProperties => _inputDerivedProperties ??= BuildDerivedProperties(); + private Dictionary<InputModelType, Dictionary<string, InputProperty>>? _inputDerivedProperties; + private Dictionary<InputModelType, Dictionary<string, InputProperty>> InputDerivedProperties => _inputDerivedProperties ??= BuildDerivedProperties(); - private Dictionary<InputModelType, Dictionary<string, InputModelProperty>> BuildDerivedProperties() + private Dictionary<InputModelType, Dictionary<string, InputProperty>> BuildDerivedProperties() { - Dictionary<InputModelType, Dictionary<string, InputModelProperty>> derivedProperties = []; + Dictionary<InputModelType, Dictionary<string, InputProperty>> derivedProperties = []; var derivedModels = new List<InputModelType>(); EnumerateDerivedModels(_inputModel, derivedModels); foreach (var derivedModel in derivedModels) @@ -376,20 +381,21 @@ protected override PropertyProvider[] BuildProperties() { var propertiesCount = _inputModel.Properties.Count; var properties = new List<PropertyProvider>(propertiesCount + 1); - Dictionary<string, InputModelProperty> baseProperties = EnumerateBaseModels().SelectMany(m => m.Properties).GroupBy(x => x.Name).Select(g => g.First()).ToDictionary(p => p.Name) ?? []; + Dictionary<string, InputProperty> baseProperties = EnumerateBaseModels().SelectMany(m => m.Properties).GroupBy(x => x.Name).Select(g => g.First()).ToDictionary(p => p.Name) ?? []; var baseModelDiscriminator = _inputModel.BaseModel?.DiscriminatorProperty; for (int i = 0; i < propertiesCount; i++) { var property = _inputModel.Properties[i]; + var isDiscriminator = IsDiscriminator(property); - if (property.IsDiscriminator && property.Name == baseModelDiscriminator?.Name) + if (isDiscriminator && property.Name == baseModelDiscriminator?.Name) continue; var outputProperty = CodeModelGenerator.Instance.TypeFactory.CreateProperty(property, this); if (outputProperty is null) continue; - if (!property.IsDiscriminator) + if (!isDiscriminator) { var derivedProperty = InputDerivedProperties.FirstOrDefault(p => p.Value.ContainsKey(property.Name)).Value?[property.Name]; if (derivedProperty is not null) @@ -439,7 +445,7 @@ private IEnumerable<InputModelType> EnumerateBaseModels() } } - private static bool DomainEqual(InputModelProperty baseProperty, InputModelProperty derivedProperty) + private static bool DomainEqual(InputProperty baseProperty, InputProperty derivedProperty) { if (baseProperty.Type.Name != derivedProperty.Type.Name) return false; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs index c6cf6080f21..d91052f36c3 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PropertyProvider.cs @@ -18,7 +18,7 @@ public class PropertyProvider { private VariableExpression? _variable; private Lazy<ParameterProvider> _parameter; - private readonly InputModelProperty? _inputProperty; + private readonly InputProperty? _inputProperty; private readonly SerializationFormat _serializationFormat; private FormattableString? _customDescription; @@ -53,7 +53,7 @@ protected PropertyProvider() { } - internal static bool TryCreate(InputModelProperty inputProperty, TypeProvider enclosingType, [NotNullWhen(true)] out PropertyProvider? property) + internal static bool TryCreate(InputProperty inputProperty, TypeProvider enclosingType, [NotNullWhen(true)] out PropertyProvider? property) { var type = CodeModelGenerator.Instance.TypeFactory.CreateCSharpType(inputProperty.Type); if (type == null) @@ -65,7 +65,7 @@ internal static bool TryCreate(InputModelProperty inputProperty, TypeProvider en return true; } - public PropertyProvider(InputModelProperty inputProperty, TypeProvider enclosingType) + public PropertyProvider(InputProperty inputProperty, TypeProvider enclosingType) : this( inputProperty, CodeModelGenerator.Instance.TypeFactory.CreateCSharpType(inputProperty.Type) ?? throw new InvalidOperationException($"Could not create CSharpType for property {inputProperty.Name}"), @@ -73,7 +73,7 @@ public PropertyProvider(InputModelProperty inputProperty, TypeProvider enclosing { } - private PropertyProvider(InputModelProperty inputProperty, CSharpType propertyType, TypeProvider enclosingType) + private PropertyProvider(InputProperty inputProperty, CSharpType propertyType, TypeProvider enclosingType) { _inputProperty = inputProperty; if (!inputProperty.IsRequired && !propertyType.IsCollection) @@ -87,14 +87,14 @@ private PropertyProvider(InputModelProperty inputProperty, CSharpType propertyTy MethodSignatureModifiers setterModifier = propHasSetter ? MethodSignatureModifiers.Public : MethodSignatureModifiers.None; Type = inputProperty.IsReadOnly ? propertyType.OutputType : propertyType; - Modifiers = inputProperty.IsDiscriminator ? MethodSignatureModifiers.Internal : MethodSignatureModifiers.Public; + IsDiscriminator = IsDiscriminatorProperty(inputProperty); + Modifiers = IsDiscriminator ? MethodSignatureModifiers.Internal : MethodSignatureModifiers.Public; Name = inputProperty.Name == enclosingType.Name ? $"{inputProperty.Name.ToCleanName()}Property" : inputProperty.Name.ToCleanName(); Body = new AutoPropertyBody(propHasSetter, setterModifier, GetPropertyInitializationValue(propertyType, inputProperty)); WireInfo = new PropertyWireInformation(inputProperty); - IsDiscriminator = inputProperty.IsDiscriminator; InitializeParameter(DocHelpers.GetFormattableDescription(inputProperty.Summary, inputProperty.Doc) ?? FormattableStringHelpers.Empty); BuildDocs(); @@ -164,12 +164,17 @@ private void InitializeParameter(FormattableString description) public VariableExpression AsVariableExpression => _variable ??= new(Type, Name.ToVariableName()); + private static bool IsDiscriminatorProperty(InputProperty inputProperty) + { + return inputProperty is InputModelProperty mp && mp.IsDiscriminator; + } + /// <summary> /// Returns true if the property has a setter. /// </summary> - protected virtual bool PropertyHasSetter(CSharpType type, InputModelProperty inputProperty) + protected virtual bool PropertyHasSetter(CSharpType type, InputProperty inputProperty) { - if (inputProperty.IsDiscriminator) + if (IsDiscriminatorProperty(inputProperty)) { return true; } @@ -212,7 +217,7 @@ protected virtual bool PropertyHasSetter(CSharpType type, InputModelProperty inp return true; } - private ValueExpression? GetPropertyInitializationValue(CSharpType propertyType, InputModelProperty inputProperty) + private ValueExpression? GetPropertyInitializationValue(CSharpType propertyType, InputProperty inputProperty) { if (!inputProperty.IsRequired) return null; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs index 55e8d5d5a3b..10e02dd9c9f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs @@ -22,7 +22,7 @@ public class TypeFactory private Dictionary<InputType, CSharpType?> TypeCache { get; } = []; - private Dictionary<InputModelProperty, PropertyProvider?> PropertyCache { get; } = []; + private Dictionary<InputProperty, PropertyProvider?> PropertyCache { get; } = []; private IReadOnlyList<LibraryVisitor> Visitors => CodeModelGenerator.Instance.Visitors; private Dictionary<InputType, IReadOnlyList<TypeProvider>> SerializationsCache { get; } = []; @@ -227,7 +227,7 @@ protected virtual ParameterProvider CreateParameterCore(InputParameter parameter /// </summary> /// <param name="property">The input property.</param> /// <returns>The property provider.</returns> - public PropertyProvider? CreateProperty(InputModelProperty property, TypeProvider enclosingType) + public PropertyProvider? CreateProperty(InputProperty property, TypeProvider enclosingType) { if (PropertyCache.TryGetValue(property, out var propertyProvider)) return propertyProvider; @@ -243,7 +243,7 @@ protected virtual ParameterProvider CreateParameterCore(InputParameter parameter /// <param name="property">The input model property.</param> /// <param name="enclosingType">The enclosing type.</param> /// <returns>An instance of <see cref="PropertyProvider"/>.</returns> - protected virtual PropertyProvider? CreatePropertyCore(InputModelProperty property, TypeProvider enclosingType) + protected virtual PropertyProvider? CreatePropertyCore(InputProperty property, TypeProvider enclosingType) { PropertyProvider.TryCreate(property, enclosingType, out var propertyProvider); if (Visitors.Count == 0) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/InputLibraryVisitorTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/InputLibraryVisitorTests.cs index 45ea4ac2386..a14f7bba573 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/InputLibraryVisitorTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/InputLibraryVisitorTests.cs @@ -126,7 +126,7 @@ public PreVisitor(bool cleanupReference = false) return base.PreVisitModel(inputModel, typeProvider); } - protected internal override PropertyProvider? PreVisitProperty(InputModelProperty inputModelProperty, PropertyProvider? propertyProvider) + protected internal override PropertyProvider? PreVisitProperty(InputProperty inputModelProperty, PropertyProvider? propertyProvider) { if (_cleanupReference && inputModelProperty.Type.Name == "Model1") { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs index 828edec66ce..0876af726f5 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/CanonicalTypeProviderTests.cs @@ -174,7 +174,7 @@ private static InputType GetSpecType() [ InputFactory.Property("IntProperty", InputPrimitiveType.Int32, wireName: "intProperty"), InputFactory.Property("StringProperty", InputPrimitiveType.String, wireName: "stringProperty"), - new InputModelProperty("NullWireInfoProperty", InputModelPropertyKind.Property, null, null, InputPrimitiveType.String, false, false, false, "NullWireInfoProperty", new InputSerializationOptions()) + new InputModelProperty("NullWireInfoProperty", null, null, InputPrimitiveType.String, false, false, null, false, "NullWireInfoProperty", new InputSerializationOptions()) ]; return InputFactory.Model("TestName", "Sample.Models", properties: properties); } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs index 873caf0b949..fe0ad623c5e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs @@ -885,10 +885,10 @@ public void TestBuildModelWithNonBodyPropertyKinds() "ModelWithNonBodyPropertyKinds", properties: [ - InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Header), - InputFactory.Property("cat", InputPrimitiveType.String, wireName: "x-cat", isRequired: true, kind: InputModelPropertyKind.Query), - InputFactory.Property("bird", InputPrimitiveType.String, isRequired: true, kind: InputModelPropertyKind.Path), - InputFactory.Property("snake", InputFactory.StringEnum("snake", [("value", "value")], isExtensible: true), isRequired: true, isReadOnly: true, kind: InputModelPropertyKind.Header), + InputFactory.HeaderParameter("foo", InputPrimitiveType.String, isRequired: true), + InputFactory.QueryParameter("cat", InputPrimitiveType.String, serializedName: "x-cat", isRequired: true), + InputFactory.PathParameter("bird", InputPrimitiveType.String, isRequired: true), + InputFactory.HeaderParameter("snake", InputFactory.StringEnum("snake", [("value", "value")], isExtensible: true), isRequired: true, isReadOnly: true), InputFactory.Property("bar", InputPrimitiveType.Int32, isRequired: true) ]); var modelProvider = CodeModelGenerator.Instance.TypeFactory.CreateModel(inputModel); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs index 2a7e9f5578a..51b76c7349d 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs @@ -223,20 +223,87 @@ public static InputModelProperty Property( string? wireName = null, string? summary = null, string? serializedName = null, - string? doc = null, - InputModelPropertyKind kind = InputModelPropertyKind.Property) + string? doc = null) { return new InputModelProperty( - name, - kind, - summary, - doc ?? $"Description for {name}", - type, - isRequired, - isReadOnly, - isDiscriminator, - serializedName, - new(json: new(wireName ?? name.ToVariableName()))); + name: name, + summary: summary, + doc: doc ?? $"Description for {name}", + type: type, + isRequired: isRequired, + isReadOnly: isReadOnly, + access: null, + isDiscriminator: isDiscriminator, + serializedName: serializedName ?? wireName ?? name.ToVariableName(), + serializationOptions: new(json: new(wireName ?? name.ToVariableName()))); + } + + public static InputHeaderParameter HeaderParameter( + string name, + InputType type, + bool isRequired = false, + bool isReadOnly = false, + string? summary = null, + string? doc = null, + string? collectionFormat = null, + string? serializedName = null) + { + return new InputHeaderParameter( + name: name, + summary: summary, + doc: doc ?? $"Description for {name}", + type: type, + isRequired: isRequired, + isReadOnly: isReadOnly, + access: null, + collectionFormat: collectionFormat, + serializedName: serializedName ?? name); + } + + public static InputQueryParameter QueryParameter( + string name, + InputType type, + bool isRequired = false, + bool isReadOnly = false, + string? summary = null, + string? doc = null, + string? collectionFormat = null, + string? serializedName = null, + bool explode = false) + { + return new InputQueryParameter( + name: name, + summary: summary, + doc: doc ?? $"Description for {name}", + type: type, + isRequired: isRequired, + isReadOnly: isReadOnly, + access: null, + serializedName: serializedName ?? name, + collectionFormat: collectionFormat, + explode: explode); + } + + public static InputPathParameter PathParameter( + string name, + InputType type, + bool isRequired = false, + bool isReadOnly = false, + string? summary = null, + string? doc = null, + string? serializedName = null, + bool allowReserved = false) + { + return new InputPathParameter( + name: name, + summary: summary, + doc: doc ?? $"Description for {name}", + type: type, + isRequired: isRequired, + isReadOnly: isReadOnly, + access: null, + serializedName: serializedName ?? name, + allowReserved: allowReserved); } // Replace reflection with InternalsVisibleTo after fixing https://github.com/microsoft/typespec/issues/7075")] @@ -246,7 +313,7 @@ public static InputModelType Model( string @namespace = "Sample.Models", string access = "public", InputModelTypeUsage usage = InputModelTypeUsage.Output | InputModelTypeUsage.Input | InputModelTypeUsage.Json, - IEnumerable<InputModelProperty>? properties = null, + IEnumerable<InputProperty>? properties = null, InputModelType? baseModel = null, bool modelAsStruct = false, string? discriminatedKind = null, @@ -254,7 +321,7 @@ public static InputModelType Model( IDictionary<string, InputModelType>? discriminatedModels = null, IEnumerable<InputModelType>? derivedModels = null) { - IEnumerable<InputModelProperty> propertiesList = properties ?? [Property("StringProperty", InputPrimitiveType.String)]; + IEnumerable<InputProperty> propertiesList = properties ?? [Property("StringProperty", InputPrimitiveType.String)]; var model = new InputModelType( name, @@ -269,7 +336,7 @@ public static InputModelType Model( baseModel, derivedModels is null ? [] : [.. derivedModels], discriminatedKind, - propertiesList.FirstOrDefault(p => p.IsDiscriminator), + propertiesList.FirstOrDefault(p => p is InputModelProperty modelProperty && modelProperty.IsDiscriminator), discriminatedModels is null ? new Dictionary<string, InputModelType>() : discriminatedModels.AsReadOnly(), additionalProperties, modelAsStruct, diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json index 936d857acfd..61db90320d9 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json @@ -3055,8 +3055,7 @@ "readOnly": false, "decorators": [], "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.requiredHeader", - "discriminator": false, - "flatten": false + "correspondingMethodParams": [] }, { "$id": "394", @@ -3075,8 +3074,7 @@ "readOnly": false, "decorators": [], "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.optionalHeader", - "discriminator": false, - "flatten": false + "correspondingMethodParams": [] }, { "$id": "396", @@ -3095,8 +3093,7 @@ "readOnly": false, "decorators": [], "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.requiredQuery", - "discriminator": false, - "flatten": false + "correspondingMethodParams": [] }, { "$id": "398", @@ -3115,8 +3112,7 @@ "readOnly": false, "decorators": [], "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.optionalQuery", - "discriminator": false, - "flatten": false + "correspondingMethodParams": [] } ] } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/content-negotiation/tspCodeModel.json b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/content-negotiation/tspCodeModel.json index a21caad1dfb..08ee18779fc 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/content-negotiation/tspCodeModel.json +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/content-negotiation/tspCodeModel.json @@ -235,8 +235,7 @@ "readOnly": false, "decorators": [], "crossLanguageDefinitionId": "Payload.ContentNegotiation.DifferentBody.PngImageAsJson.contentType", - "discriminator": false, - "flatten": false + "correspondingMethodParams": [] }, { "$id": "30", diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/tspCodeModel.json b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/tspCodeModel.json index 146fae0acb4..8e0fa0c3ca5 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/tspCodeModel.json +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/tspCodeModel.json @@ -1787,8 +1787,7 @@ "readOnly": false, "decorators": [], "crossLanguageDefinitionId": "Payload.MultiPart.FormData.HttpParts.NonString.float.Request.temperature.anonymous.contentType", - "discriminator": false, - "flatten": false + "correspondingMethodParams": [] } ] } diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/type/model/visibility/tspCodeModel.json b/packages/http-client-csharp/generator/TestProjects/Spector/http/type/model/visibility/tspCodeModel.json index a0e684cffaf..794a0ce3703 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/type/model/visibility/tspCodeModel.json +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/type/model/visibility/tspCodeModel.json @@ -204,8 +204,7 @@ "readOnly": false, "decorators": [], "crossLanguageDefinitionId": "Type.Model.Visibility.VisibilityModel.queryProp", - "discriminator": false, - "flatten": false + "correspondingMethodParams": [] }, { "$id": "27",