diff --git a/packages/http-client-csharp/emitter/src/lib/converter.ts b/packages/http-client-csharp/emitter/src/lib/converter.ts index 592e82dbac..df3a7a72ec 100644 --- a/packages/http-client-csharp/emitter/src/lib/converter.ts +++ b/packages/http-client-csharp/emitter/src/lib/converter.ts @@ -14,7 +14,6 @@ import { SdkEnumValueType, SdkModelPropertyType, SdkModelType, - SdkTupleType, SdkType, SdkUnionType, UsageFlags, @@ -24,7 +23,6 @@ import { import { Model } from "@typespec/compiler"; import { InputEnumTypeValue } from "../type/input-enum-type-value.js"; import { InputModelProperty } from "../type/input-model-property.js"; -import { InputTypeKind } from "../type/input-type-kind.js"; import { InputArrayType, InputDateTimeType, @@ -68,7 +66,7 @@ export function fromSdkType( if (sdkType.kind === "utcDateTime" || sdkType.kind === "offsetDateTime") return fromSdkDateTimeType(sdkType); if (sdkType.kind === "duration") return fromSdkDurationType(sdkType as SdkDurationType); - if (sdkType.kind === "tuple") return fromTupleType(sdkType); + if (sdkType.kind === "tuple") return fromTupleType(); // TODO -- only in operations we could have these types, considering we did not adopt getAllOperations from TCGC yet, this should be fine. // we need to resolve these conversions when we adopt getAllOperations if (sdkType.kind === "credential") throw new Error("Credential type is not supported yet."); @@ -86,103 +84,106 @@ export function fromSdkModelType( const modelTypeName = modelType.name; let inputModelType = models.get(modelTypeName); if (!inputModelType) { - const baseModelHasDiscriminator = hasDiscriminator(modelType.baseModel); inputModelType = { - Kind: InputTypeKind.Model, + Kind: "model", Name: modelTypeName, - Namespace: getFullNamespaceString((modelType.__raw as Model).namespace), - Accessibility: getAccessOverride( + Namespace: getFullNamespaceString((modelType.__raw as Model).namespace), // TODO -- use the value from TCGC when this is included in TCGC + Access: getAccessOverride( context, modelType.__raw as Model ) /* when tcgc provide a way to identify if the access is override or not, we can get the accessibility from the modelType.access */, - Deprecated: modelType.deprecation, + Usage: fromUsageFlags(modelType.usage), + Deprecation: modelType.deprecation, Description: modelType.description, - DiscriminatorPropertyName: baseModelHasDiscriminator - ? undefined - : getDiscriminatorPropertyNameFromCurrentModel(modelType), DiscriminatorValue: modelType.discriminatorValue, - Usage: fromUsageFlags(modelType.usage), } as InputModelType; models.set(modelTypeName, inputModelType); + inputModelType.AdditionalProperties = modelType.additionalProperties + ? fromSdkType(modelType.additionalProperties, context, models, enums) + : undefined; + + const propertiesDict = new Map(); + for (const property of modelType.properties) { + if (property.kind !== "property") { + continue; + } + const ourProperties = fromSdkModelProperty( + property, + { + ModelName: modelTypeName, + Namespace: inputModelType.Namespace, + } as LiteralTypeContext, + [] + ); + propertiesDict.set(property, ourProperties); + } + + inputModelType.DiscriminatorProperty = modelType.discriminatorProperty + ? propertiesDict.get(modelType.discriminatorProperty)![0] + : undefined; + inputModelType.BaseModel = modelType.baseModel ? fromSdkModelType(modelType.baseModel, context, models, enums) : undefined; - inputModelType.InheritedDictionaryType = modelType.additionalProperties - ? { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: fromSdkType(modelType.additionalProperties, context, models, enums), - } - : undefined; - inputModelType.Properties = modelType.properties - .filter((p) => !(p as SdkBodyModelPropertyType).discriminator || !baseModelHasDiscriminator) - .filter((p) => p.kind !== "header" && p.kind !== "query" && p.kind !== "path") - .map((p) => - fromSdkModelProperty( - p, - { - ModelName: inputModelType?.Name, - Namespace: inputModelType?.Namespace, - } as LiteralTypeContext, - [] - ) - ) - .flat(); + inputModelType.Properties = Array.from(propertiesDict.values()).flat(); + + if (modelType.discriminatedSubtypes) { + const discriminatedSubtypes: Record = {}; + for (const key in modelType.discriminatedSubtypes) { + const subtype = modelType.discriminatedSubtypes[key]; + discriminatedSubtypes[key] = fromSdkModelType(subtype, context, models, enums); + } + inputModelType.DiscriminatedSubtypes = discriminatedSubtypes; + } } return inputModelType; function fromSdkModelProperty( - propertyType: SdkModelPropertyType, + property: SdkBodyModelPropertyType, literalTypeContext: LiteralTypeContext, flattenedNamePrefixes: string[] ): InputModelProperty[] { - if (propertyType.kind !== "property" || !propertyType.flatten) { - const serializedName = - propertyType.kind === "property" - ? (propertyType as SdkBodyModelPropertyType).serializedName - : ""; + // TODO -- we should consolidate the flatten somewhere else + if (!property.flatten) { + const serializedName = property.serializedName; literalTypeContext.PropertyName = serializedName; - const isRequired = - propertyType.kind === "path" || propertyType.kind === "body" - ? true - : !propertyType.optional; // TO-DO: SdkBodyParameter lacks of optional - const isDiscriminator = - propertyType.kind === "property" && propertyType.discriminator ? true : false; + const isRequired = !property.optional; + const isDiscriminator = property.discriminator; const modelProperty: InputModelProperty = { - Name: propertyType.name, + Name: property.name, SerializedName: serializedName, - Description: propertyType.description ?? (isDiscriminator ? "Discriminator" : ""), - Type: fromSdkType(propertyType.type, context, models, enums, literalTypeContext), + Description: property.description ?? (isDiscriminator ? "Discriminator" : ""), + Type: fromSdkType( + property.type, + context, + models, + enums, + isDiscriminator ? undefined : literalTypeContext // this is a workaround because the type of discriminator property in derived models is always literal and we wrap literal into enums, which leads to a lot of extra enum types, adding this check to avoid them + ), IsRequired: isRequired, - IsReadOnly: propertyType.kind === "property" && isReadOnly(propertyType), + IsReadOnly: isReadOnly(property), IsDiscriminator: isDiscriminator === true ? true : undefined, FlattenedNames: flattenedNamePrefixes.length > 0 - ? flattenedNamePrefixes.concat(propertyType.name) + ? flattenedNamePrefixes.concat(property.name) : undefined, }; return [modelProperty]; } - let flattenedProperties: InputModelProperty[] = []; - const modelPropertyType = propertyType as SdkBodyModelPropertyType; - const childPropertiesToFlatten = (modelPropertyType.type as SdkModelType).properties; - const newFlattenedNamePrefixes = flattenedNamePrefixes.concat(modelPropertyType.serializedName); - for (let index = 0; index < childPropertiesToFlatten.length; index++) { - flattenedProperties = flattenedProperties.concat( - fromSdkModelProperty( - childPropertiesToFlatten[index], - literalTypeContext, - newFlattenedNamePrefixes - ) + const flattenedProperties: InputModelProperty[] = []; + const childPropertiesToFlatten = (property.type as SdkModelType).properties; + const newFlattenedNamePrefixes = flattenedNamePrefixes.concat(property.serializedName); + for (const childProperty of childPropertiesToFlatten) { + if (childProperty.kind !== "property") continue; + flattenedProperties.push( + ...fromSdkModelProperty(childProperty, literalTypeContext, newFlattenedNamePrefixes) ); } @@ -190,25 +191,6 @@ export function fromSdkModelType( } } -function getDiscriminatorPropertyNameFromCurrentModel(model?: SdkModelType): string | undefined { - if (model == null) return undefined; - - const discriminatorProperty = model.properties.find( - (p) => (p as SdkBodyModelPropertyType).discriminator - ); - if (discriminatorProperty) return discriminatorProperty.name; - - return undefined; -} - -function hasDiscriminator(model?: SdkModelType): boolean { - if (model == null) return false; - - if (model.properties.some((p) => (p as SdkBodyModelPropertyType).discriminator)) return true; - - return hasDiscriminator(model.baseModel); -} - export function fromSdkEnumType( enumType: SdkEnumType, context: SdkContext, @@ -259,7 +241,7 @@ function fromSdkDurationType(durationType: SdkDurationType): InputDurationType { } // TODO: tuple is not officially supported -function fromTupleType(tupleType: SdkTupleType): InputPrimitiveType { +function fromTupleType(): InputPrimitiveType { return { Kind: "any", }; @@ -277,7 +259,7 @@ function fromUnionType( context: SdkContext, models: Map, enums: Map -): InputUnionType | InputType { +): InputUnionType { const variantTypes: InputType[] = []; for (const value of union.values) { const variantType = fromSdkType(value, context, models, enums); diff --git a/packages/http-client-csharp/emitter/src/type/input-type-kind.ts b/packages/http-client-csharp/emitter/src/type/input-type-kind.ts deleted file mode 100644 index 7916ee8a06..0000000000 --- a/packages/http-client-csharp/emitter/src/type/input-type-kind.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -export enum InputTypeKind { - Model = "Model", -} 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 2981a44ce6..2740c37687 100644 --- a/packages/http-client-csharp/emitter/src/type/input-type.ts +++ b/packages/http-client-csharp/emitter/src/type/input-type.ts @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -import { SdkBuiltInKinds } from "@azure-tools/typespec-client-generator-core"; +import { AccessFlags, SdkBuiltInKinds } from "@azure-tools/typespec-client-generator-core"; import { DateTimeKnownEncoding, DurationKnownEncoding } from "@typespec/compiler"; import { InputEnumTypeValue } from "./input-enum-type-value.js"; import { InputModelProperty } from "./input-model-property.js"; -import { InputTypeKind } from "./input-type-kind.js"; interface InputTypeBase { Kind: string; Description?: string; + Deprecation?: string; } export type InputType = @@ -71,23 +71,21 @@ export function isInputUnionType(type: InputType): type is InputUnionType { } export interface InputModelType extends InputTypeBase { - Kind: InputTypeKind.Model; // TODO -- will change to TCGC value in future refactor + Kind: "model"; + Properties: InputModelProperty[]; Name: string; Namespace?: string; - Accessibility?: string; - Deprecated?: string; - Description?: string; - Usage: string; - Properties: InputModelProperty[]; - BaseModel?: InputModelType; - DiscriminatorPropertyName?: string; + Access?: AccessFlags; + Usage: string; // TODO -- replace this with UsageFlags in TCGC + AdditionalProperties?: InputType; DiscriminatorValue?: string; - DerivedModels?: InputModelType[]; - InheritedDictionaryType?: InputDictionaryType; + DiscriminatedSubtypes?: Record; + DiscriminatorProperty?: InputModelProperty; + BaseModel?: InputModelType; } export function isInputModelType(type: InputType): type is InputModelType { - return type.Kind === InputTypeKind.Model; + return type.Kind === "model"; } 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 426f18a75d..7ccc8e5cd2 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 @@ -3,7 +3,6 @@ import assert, { deepStrictEqual, strictEqual } from "assert"; import { beforeEach, describe, it } from "vitest"; import { createModel } from "../../src/lib/client-model-builder.js"; import { InputModelProperty } from "../../src/type/input-model-property.js"; -import { InputDictionaryType } from "../../src/type/input-type.js"; import { createEmitterContext, createEmitterTestHost, @@ -57,10 +56,10 @@ op test(@body input: Pet): Pet; const catModel = models.find((m) => m.Name === "Cat"); const dogModel = models.find((m) => m.Name === "Dog"); // assert the discriminator property name - deepStrictEqual("kind", petModel?.DiscriminatorPropertyName); + deepStrictEqual("kind", petModel?.DiscriminatorProperty?.Name); // assert we have a property corresponding to the discriminator property above on the base model const discriminatorProperty = petModel?.Properties.find( - (p) => p.Name === petModel?.DiscriminatorPropertyName + (p) => p === petModel?.DiscriminatorProperty ); deepStrictEqual( { @@ -78,29 +77,29 @@ op test(@body input: Pet): Pet; } as InputModelProperty, discriminatorProperty ); - // assert we will NOT have a DiscriminatorPropertyName on the derived models + // assert we will NOT have a DiscriminatorProperty on the derived models assert( - catModel?.DiscriminatorPropertyName === undefined, - "Cat model should not have the discriminator property name" + catModel?.DiscriminatorProperty === undefined, + "Cat model should not have the discriminator property" ); assert( - dogModel?.DiscriminatorPropertyName === undefined, - "Dog model should not have the discriminator property name" + dogModel?.DiscriminatorProperty === undefined, + "Dog model should not have the discriminator property" ); // assert we will NOT have a property corresponding to the discriminator property on the derived models const catDiscriminatorProperty = catModel?.Properties.find( - (p) => p.Name === petModel?.DiscriminatorPropertyName + (p) => p === petModel?.DiscriminatorProperty ); const dogDiscriminatorProperty = dogModel?.Properties.find( - (p) => p.Name === petModel?.DiscriminatorPropertyName + (p) => p === petModel?.DiscriminatorProperty ); assert( catDiscriminatorProperty === undefined, - "Cat model should not have the discriminator property" + "Cat model should not have the discriminator property in the properties list" ); assert( dogDiscriminatorProperty === undefined, - "Dog model should not have the discriminator property" + "Dog model should not have the discriminator property in the properties list" ); }); @@ -148,11 +147,9 @@ op test(@body input: Pet): Pet; const pet = models.find((m) => m.Name === "Pet"); assert(pet !== undefined); // assert the discriminator property name - strictEqual("kind", pet?.DiscriminatorPropertyName); + 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.Name === pet?.DiscriminatorPropertyName - ); + const discriminatorProperty = pet?.Properties.find((p) => p === pet?.DiscriminatorProperty); deepStrictEqual( { Name: "kind", @@ -199,16 +196,14 @@ op test(@body input: Pet): Pet; assert(cat.BaseModel === pet); // assert we will NOT have a DiscriminatorPropertyName on the derived models assert( - cat.DiscriminatorPropertyName === undefined, - "Cat model should not have the discriminator property name" + cat.DiscriminatorProperty === undefined, + "Cat model should not have the discriminator property" ); // assert we will NOT have a property corresponding to the discriminator property on the derived models - const catDiscriminatorProperty = cat.Properties.find( - (p) => p.Name === pet.DiscriminatorPropertyName - ); + const catDiscriminatorProperty = cat.Properties.find((p) => p === pet.DiscriminatorProperty); assert( catDiscriminatorProperty === undefined, - "Cat model should not have the discriminator property" + "Cat model should not have the discriminator property in the properties list" ); // verify derived model Dog @@ -216,18 +211,16 @@ op test(@body input: Pet): Pet; assert(dog !== undefined); assert(dog.DiscriminatorValue === "Dog"); assert(dog.BaseModel === pet); - // assert we will NOT have a DiscriminatorPropertyName on the derived models + // assert we will NOT have a DiscriminatorProperty on the derived models assert( - dog.DiscriminatorPropertyName === undefined, - "Dog model should not have the discriminator property name" + dog.DiscriminatorProperty === undefined, + "Dog model should not have the discriminator property" ); // assert we will NOT have a property corresponding to the discriminator property on the derived models - const dogDiscriminatorProperty = dog.Properties.find( - (p) => p.Name === pet.DiscriminatorPropertyName - ); + const dogDiscriminatorProperty = dog.Properties.find((p) => p === pet.DiscriminatorProperty); assert( dogDiscriminatorProperty === undefined, - "Dog model should not have the discriminator property" + "Dog model should not have the discriminator property in the properties list" ); }); @@ -275,11 +268,9 @@ op test(@body input: Pet): Pet; const pet = models.find((m) => m.Name === "Pet"); assert(pet !== undefined); // assert the discriminator property name - strictEqual("kind", pet?.DiscriminatorPropertyName); + 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.Name === pet?.DiscriminatorPropertyName - ); + const discriminatorProperty = pet?.Properties.find((p) => p === pet?.DiscriminatorProperty); deepStrictEqual( { Name: "kind", @@ -326,16 +317,14 @@ op test(@body input: Pet): Pet; assert(cat.BaseModel === pet); // assert we will NOT have a DiscriminatorPropertyName on the derived models assert( - cat.DiscriminatorPropertyName === undefined, - "Cat model should not have the discriminator property name" + cat.DiscriminatorProperty === undefined, + "Cat model should not have the discriminator property" ); // assert we will NOT have a property corresponding to the discriminator property on the derived models - const catDiscriminatorProperty = cat.Properties.find( - (p) => p.Name === pet.DiscriminatorPropertyName - ); + const catDiscriminatorProperty = cat.Properties.find((p) => p === pet.DiscriminatorProperty); assert( catDiscriminatorProperty === undefined, - "Cat model should not have the discriminator property" + "Cat model should not have the discriminator property in the properties list" ); // verify derived model Dog @@ -343,18 +332,16 @@ op test(@body input: Pet): Pet; assert(dog !== undefined); assert(dog.DiscriminatorValue === "dog"); assert(dog.BaseModel === pet); - // assert we will NOT have a DiscriminatorPropertyName on the derived models + // assert we will NOT have a DiscriminatorProperty on the derived models assert( - dog.DiscriminatorPropertyName === undefined, + dog.DiscriminatorProperty === undefined, "Dog model should not have the discriminator property name" ); // assert we will NOT have a property corresponding to the discriminator property on the derived models - const dogDiscriminatorProperty = dog.Properties.find( - (p) => p.Name === pet.DiscriminatorPropertyName - ); + const dogDiscriminatorProperty = dog.Properties.find((p) => p === pet.DiscriminatorProperty); assert( dogDiscriminatorProperty === undefined, - "Dog model should not have the discriminator property" + "Dog model should not have the discriminator property in the properties list" ); }); }); @@ -441,65 +428,32 @@ op op5(@body body: ExtendsFooArray): ExtendsFooArray; // assert the inherited dictionary type is expected deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "any", - Encode: undefined, - }, - } as InputDictionaryType, - extendsUnknownModel.InheritedDictionaryType + Kind: "any", + Encode: undefined, + }, + extendsUnknownModel.AdditionalProperties ); deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "string", - Encode: undefined, - }, - } as InputDictionaryType, - extendsStringModel.InheritedDictionaryType + Kind: "string", + Encode: undefined, + }, + extendsStringModel.AdditionalProperties ); deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "int32", - Encode: undefined, - }, - } as InputDictionaryType, - extendsInt32Model.InheritedDictionaryType + Kind: "int32", + Encode: undefined, + }, + extendsInt32Model.AdditionalProperties ); + deepStrictEqual(fooModel, extendsFooModel.AdditionalProperties); deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, + Kind: "array", ValueType: fooModel, - } as InputDictionaryType, - extendsFooModel.InheritedDictionaryType - ); - deepStrictEqual( - { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "array", - ValueType: fooModel, - }, - } as InputDictionaryType, - extendsFooArrayModel.InheritedDictionaryType + }, + extendsFooArrayModel.AdditionalProperties ); }); }); @@ -586,65 +540,32 @@ op op5(@body body: IsFooArray): IsFooArray; // assert the inherited dictionary type is expected deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "any", - Encode: undefined, - }, - } as InputDictionaryType, - isUnknownModel.InheritedDictionaryType + Kind: "any", + Encode: undefined, + }, + isUnknownModel.AdditionalProperties ); deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "string", - Encode: undefined, - }, - } as InputDictionaryType, - isStringModel.InheritedDictionaryType + Kind: "string", + Encode: undefined, + }, + isStringModel.AdditionalProperties ); deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "int32", - Encode: undefined, - }, - } as InputDictionaryType, - isInt32Model.InheritedDictionaryType + Kind: "int32", + Encode: undefined, + }, + isInt32Model.AdditionalProperties ); + deepStrictEqual(fooModel, isFooModel.AdditionalProperties); deepStrictEqual( { - Kind: "dict", - KeyType: { - Kind: "string", - }, + Kind: "array", ValueType: fooModel, - } as InputDictionaryType, - isFooModel.InheritedDictionaryType - ); - deepStrictEqual( - { - Kind: "dict", - KeyType: { - Kind: "string", - }, - ValueType: { - Kind: "array", - ValueType: fooModel, - }, - } as InputDictionaryType, - isFooArrayModel.InheritedDictionaryType + }, + isFooArrayModel.AdditionalProperties ); }); }); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/MrwSerializationTypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/MrwSerializationTypeProviderTests.cs index eb9db7badf..59c95adfd1 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/MrwSerializationTypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/MrwSerializationTypeProviderTests.cs @@ -52,7 +52,7 @@ public void Teardown() public void TestBuildImplements() { // mock the model type provider - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var mockModelTypeProvider = new ModelProvider(inputModel); var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var interfaces = jsonMrwSerializationTypeProvider.Implements; @@ -69,7 +69,7 @@ public void TestBuildImplements() [Test] public void TestBuildJsonModelWriteCoreMethod() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var mockModelTypeProvider = new ModelProvider(inputModel); var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var method = jsonMrwSerializationTypeProvider.BuildJsonModelWriteCoreMethod(); @@ -105,7 +105,7 @@ public void TestBuildJsonModelWriteCoreMethod() [Test] public void BuildJsonModelWriteMethodObjectDeclaration() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, true); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, true); var mockModelTypeProvider = new ModelProvider(inputModel); var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var method = jsonMrwSerializationTypeProvider.BuildJsonModelWriteMethodObjectDeclaration(); @@ -140,7 +140,7 @@ public void BuildJsonModelWriteMethodObjectDeclaration() [Test] public void TestBuildJsonModelCreateMethod() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var mockModelTypeProvider = new ModelProvider(inputModel); var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var method = jsonMrwSerializationTypeProvider.BuildJsonModelCreateMethod(); @@ -161,7 +161,7 @@ public void TestBuildJsonModelCreateMethod() [Test] public void TestBuildPersistableModelWriteMethodMethod() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var mockModelTypeProvider = new ModelProvider(inputModel); var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var method = jsonMrwSerializationTypeProvider.BuildPersistableModelWriteMethod(); @@ -182,7 +182,7 @@ public void TestBuildPersistableModelWriteMethodMethod() [Test] public void TestBuildPersistableModelDeserializationMethod() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var mockModelTypeProvider = new ModelProvider(inputModel); var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var method = jsonMrwSerializationTypeProvider.BuildPersistableModelCreateMethod(); @@ -203,7 +203,7 @@ public void TestBuildPersistableModelDeserializationMethod() [Test] public void TestBuildPersistableModelGetFormatMethod() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var mockModelTypeProvider = new ModelProvider(inputModel); var jsonMrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var method = jsonMrwSerializationTypeProvider.BuildPersistableModelGetFormatFromOptionsMethod(); @@ -226,7 +226,7 @@ public void TestBuildPersistableModelGetFormatMethod() [Test] public void TestBuildSerializationConstructor() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var mockModelTypeProvider = new ModelProvider(inputModel); var MrwSerializationTypeProvider = new MrwSerializationTypeProvider(mockModelTypeProvider, inputModel); var constructor = MrwSerializationTypeProvider.BuildSerializationConstructor(); @@ -244,7 +244,7 @@ public void TestBuildSerializationConstructor() [Test] public void TestBuildFields() { - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, Array.Empty(), null, new List(), null, null, new Dictionary(), null, false); var model = new ModelProvider(inputModel); var typeProvider = new MrwSerializationTypeProvider(model, inputModel); var fields = typeProvider.Fields; @@ -268,7 +268,7 @@ public void TestBuildConstructor_ValidateConstructors() new InputModelProperty("requiredDictionary", "requiredDictionary", "", new InputDictionaryType("Dictionary", new InputPrimitiveType(InputPrimitiveTypeKind.String), new InputPrimitiveType(InputPrimitiveTypeKind.String)), true, false, false), }; - var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, null, false); + var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, new Dictionary(), null, false); var ModelProvider = new ModelProvider(inputModel); var serializationModelTypeProvider = new MrwSerializationTypeProvider(ModelProvider, inputModel); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs index e5805daef1..f7d761eb7d 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/ExampleMockValueBuilder.cs @@ -186,9 +186,9 @@ private static InputExampleValue BuildModelExampleValue(InputModelType model, bo var result = InputExampleValue.Object(model, dict); visitedModels.Add(model); // if this model has a discriminator, we should return a derived type - if (model.DiscriminatorPropertyName != null) + if (model.DiscriminatorProperty != null) { - var derived = model.DerivedModels.FirstOrDefault(); + var derived = model.DiscriminatedSubtypes.Values.FirstOrDefault(); if (derived is null) { return InputExampleValue.Null(model); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs index a9da09a342..c16f37266c 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/InputModelType.cs @@ -10,28 +10,29 @@ namespace Microsoft.Generator.CSharp.Input public class InputModelType : InputType { // 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? modelNamespace, string? accessibility, string? deprecated, string? description, InputModelTypeUsage usage, IReadOnlyList properties, InputModelType? baseModel, IReadOnlyList derivedModels, string? discriminatorValue, string? discriminatorPropertyName, InputDictionaryType? inheritedDictionaryType, bool modelAsStruct) + public InputModelType(string name, string? modelNamespace, string? access, string? deprecation, string? description, InputModelTypeUsage usage, IReadOnlyList properties, InputModelType? baseModel, IReadOnlyList derivedModels, string? discriminatorValue, InputModelProperty? discriminatorProperty, IReadOnlyDictionary discriminatedSubtypes, InputType? additionalProperties, bool modelAsStruct) : base(name) { Namespace = modelNamespace; - Accessibility = accessibility; - Deprecated = deprecated; + Access = access; + Deprecation = deprecation; Description = description; Usage = usage; Properties = properties; BaseModel = baseModel; DerivedModels = derivedModels; DiscriminatorValue = discriminatorValue; - DiscriminatorPropertyName = discriminatorPropertyName; - InheritedDictionaryType = inheritedDictionaryType; + DiscriminatorProperty = discriminatorProperty; + DiscriminatedSubtypes = discriminatedSubtypes; + AdditionalProperties = additionalProperties; IsUnknownDiscriminatorModel = false; IsPropertyBag = false; ModelAsStruct = modelAsStruct; } public string? Namespace { get; internal set; } - public string? Accessibility { get; internal set; } - public string? Deprecated { get; internal set; } + public string? Access { get; internal set; } + public string? Deprecation { get; internal set; } public string? Description { get; internal set; } public InputModelTypeUsage Usage { get; internal set; } public IReadOnlyList Properties { get; internal set; } @@ -39,8 +40,9 @@ public InputModelType(string name, string? modelNamespace, string? accessibility public InputModelType? BaseModel { get; internal set; } public IReadOnlyList DerivedModels { get; internal set; } public string? DiscriminatorValue { get; internal set; } - public string? DiscriminatorPropertyName { get; internal set; } - public InputDictionaryType? InheritedDictionaryType { get; internal set; } + public InputModelProperty? DiscriminatorProperty{ get; internal set; } + public IReadOnlyDictionary DiscriminatedSubtypes { get; internal set; } + public InputType? AdditionalProperties { get; internal set; } public bool IsUnknownDiscriminatorModel { get; init; } public bool IsPropertyBag { get; init; } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs index c42fdf9f95..a190642ffa 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputModelTypeConverter.cs @@ -33,7 +33,7 @@ public static InputModelType CreateModelType(ref Utf8JsonReader reader, string? id = id ?? throw new JsonException(); // create an empty model to resolve circular references - var model = new InputModelType(name!, null, null, null, null, InputModelTypeUsage.None, null!, null, new List(), null, null, null, false); + var model = new InputModelType(name!, null, null, null, null, InputModelTypeUsage.None, null!, null, null!, null, null, null!, null, false); resolver.AddReference(id, model); string? ns = null; @@ -41,11 +41,12 @@ public static InputModelType CreateModelType(ref Utf8JsonReader reader, string? string? deprecated = null; string? description = null; string? usageString = null; - string? discriminatorPropertyName = null; + InputModelProperty? discriminatorProperty = null; string? discriminatorValue = null; - InputDictionaryType? inheritedDictionaryType = null; + InputType? additionalProperties = null; InputModelType? baseModel = null; IReadOnlyList? properties = null; + IReadOnlyDictionary? discriminatedSubtypes = null; bool modelAsStruct = false; // read all possible properties and throw away the unknown properties @@ -53,15 +54,16 @@ public static InputModelType CreateModelType(ref Utf8JsonReader reader, string? { var isKnownProperty = reader.TryReadString(nameof(InputModelType.Name), ref name) || reader.TryReadString(nameof(InputModelType.Namespace), ref ns) - || reader.TryReadString(nameof(InputModelType.Accessibility), ref accessibility) - || reader.TryReadString(nameof(InputModelType.Deprecated), ref deprecated) + || reader.TryReadString(nameof(InputModelType.Access), ref accessibility) + || reader.TryReadString(nameof(InputModelType.Deprecation), ref deprecated) || reader.TryReadString(nameof(InputModelType.Description), ref description) || reader.TryReadString(nameof(InputModelType.Usage), ref usageString) - || reader.TryReadString(nameof(InputModelType.DiscriminatorPropertyName), ref discriminatorPropertyName) + || reader.TryReadWithConverter(nameof(InputModelType.DiscriminatorProperty), options, ref discriminatorProperty) || reader.TryReadString(nameof(InputModelType.DiscriminatorValue), ref discriminatorValue) - || reader.TryReadWithConverter(nameof(InputModelType.InheritedDictionaryType), options, ref inheritedDictionaryType) + || reader.TryReadWithConverter(nameof(InputModelType.AdditionalProperties), options, ref additionalProperties) || reader.TryReadWithConverter(nameof(InputModelType.BaseModel), options, ref baseModel) || reader.TryReadWithConverter(nameof(InputModelType.Properties), options, ref properties) + || reader.TryReadWithConverter(nameof(InputModelType.DiscriminatedSubtypes), options, ref discriminatedSubtypes) || reader.TryReadBoolean(nameof(InputModelType.ModelAsStruct), ref modelAsStruct); if (!isKnownProperty) @@ -72,20 +74,27 @@ public static InputModelType CreateModelType(ref Utf8JsonReader reader, string? model.Name = name ?? throw new JsonException("InputModelType must have name"); model.Namespace = ns; - model.Accessibility = accessibility; - model.Deprecated = deprecated; + model.Access = accessibility; + model.Deprecation = deprecated; model.Description = description; var parsedUsage = Enum.TryParse(usageString, ignoreCase: true, out var usage) ? usage : InputModelTypeUsage.None; // TO-DO: Manually add JSON usage flag for now until support for parsing this is added to the TSP https://github.com/microsoft/typespec/issues/3392 parsedUsage |= InputModelTypeUsage.Json; model.Usage = parsedUsage; model.DiscriminatorValue = discriminatorValue; - model.DiscriminatorPropertyName = discriminatorPropertyName; - model.InheritedDictionaryType = inheritedDictionaryType; + model.DiscriminatorProperty = discriminatorProperty; + model.AdditionalProperties = additionalProperties; model.BaseModel = baseModel; model.Properties = properties ?? Array.Empty(); + model.DiscriminatedSubtypes = discriminatedSubtypes ?? new Dictionary(); model.ModelAsStruct = modelAsStruct; + // if this model has a base, it means this model is a derived model of the base model, add it into the list. + if (baseModel != null) + { + ((List)baseModel.DerivedModels).Add(model); + } + return model; } } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs index 3d927eee66..f6754838da 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputNamespaceConverter.cs @@ -57,15 +57,6 @@ public override void Write(Utf8JsonWriter writer, InputNamespace value, JsonSeri models ??= Array.Empty(); clients ??= Array.Empty(); - // resolve the derived models now - foreach (var model in models) - { - if (model.BaseModel is { } baseModel) - { - ((List)baseModel.DerivedModels).Add(model); - } - } - return new InputNamespace( name ?? throw new JsonException(), apiVersions, diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs index abf4ca6b1e..81a32c07eb 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.Input/src/InputTypes/Serialization/TypeSpecInputTypeConverter.cs @@ -52,7 +52,7 @@ private InputType CreateObject(ref Utf8JsonReader reader, JsonSerializerOptions private const string LiteralKind = "constant"; private const string UnionKind = "union"; - private const string ModelKind = "Model"; + private const string ModelKind = "model"; private const string EnumKind = "enum"; private const string ArrayKind = "array"; private const string DictionaryKind = "dict"; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/CodeWriterBenchmark.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/CodeWriterBenchmark.cs index dcbb68aae3..57adc82726 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/CodeWriterBenchmark.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/CodeWriterBenchmark.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; using BenchmarkDotNet.Attributes; using Microsoft.Generator.CSharp.Input; using Microsoft.Generator.CSharp.Providers; @@ -18,7 +19,7 @@ public CodeWriterBenchmark() { new InputModelProperty("MyProperty", "myProperty", "The property of mine", new InputPrimitiveType(InputPrimitiveTypeKind.Int32), true, false, false) }; - var inputModel = new InputModelType("MyModel", null, null, null, "Test model", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, null, false); + var inputModel = new InputModelType("MyModel", null, null, null, "Test model", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, new Dictionary(), null, false); var modelProvider = new ModelProvider(inputModel); _writer = new TypeProviderWriter(modelProvider); } diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs index ade7c3a083..bd66a3aba3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/ModelProvider.cs @@ -31,12 +31,12 @@ public ModelProvider(InputModelType inputModel) Description = inputModel.Description != null ? FormattableStringHelpers.FromString(inputModel.Description) : $"The {Name}."; _declarationModifiers = TypeSignatureModifiers.Partial | (inputModel.ModelAsStruct ? TypeSignatureModifiers.ReadOnly | TypeSignatureModifiers.Struct : TypeSignatureModifiers.Class); - if (inputModel.Accessibility == "internal") + if (inputModel.Access == "internal") { _declarationModifiers |= TypeSignatureModifiers.Internal; } - bool isAbstract = inputModel.DiscriminatorPropertyName is not null && inputModel.DiscriminatorValue is null; + bool isAbstract = inputModel.DiscriminatorProperty is not null && inputModel.DiscriminatorValue is null; if (isAbstract) { _declarationModifiers |= TypeSignatureModifiers.Abstract; diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Providers/ModelProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Providers/ModelProviderTests.cs index 7f7e298b97..78c2684b06 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Providers/ModelProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Providers/ModelProviderTests.cs @@ -51,7 +51,7 @@ public void BuildProperties_ValidatePropertySetters(InputModelProperty inputMode inputModelProperty }; - var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, props, null, new List(), null, null, null, false); + var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, props, null, new List(), null, null, new Dictionary(), null, false); var modelTypeProvider = new ModelProvider(inputModel); var properties = modelTypeProvider.Properties; @@ -159,7 +159,7 @@ public void BuildConstructor_ValidateConstructors() mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object); _mockPlugin?.SetValue(null, mockPluginInstance.Object); - var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, null, false); + var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, new Dictionary(), null, false); var modelTypeProvider = new ModelProvider(inputModel); var ctors = modelTypeProvider.Constructors; @@ -200,7 +200,7 @@ public void BuildModelAsStruct() mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object); _mockPlugin?.SetValue(null, mockPluginInstance.Object); - var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, null, modelAsStruct: true); + var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty(), null, null, new Dictionary(), null, modelAsStruct: true); var modelTypeProvider = new ModelProvider(inputModel); Assert.AreEqual(TypeSignatureModifiers.Public | TypeSignatureModifiers.Struct | TypeSignatureModifiers.Partial | TypeSignatureModifiers.ReadOnly, modelTypeProvider.DeclarationModifiers); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/TypeProviderWriterTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/TypeProviderWriterTests.cs index 14605e42bf..d05cb2bf8f 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/TypeProviderWriterTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/test/Writers/TypeProviderWriterTests.cs @@ -63,7 +63,7 @@ public void TypeProviderWriter_WriteModel() MockPluginSetValue(properties); var inputModel = new InputModelType("TestModel", null, "public", null, "Test model.", InputModelTypeUsage.RoundTrip, - properties, null, new List(), null, null, null, false); + properties, null, new List(), null, null, new Dictionary(), null, false); var modelProvider = new ModelProvider(inputModel); var codeFile = new TypeProviderWriter(modelProvider).Write(); @@ -81,7 +81,7 @@ public void TypeProviderWriter_WriteModelAsStruct() MockPluginSetValue(properties); var inputModel = new InputModelType("TestModel", null, "public", null, "Test model.", InputModelTypeUsage.RoundTrip, - properties, null, new List(), null, null, null, modelAsStruct: true); + properties, null, new List(), null, null, new Dictionary(), null, modelAsStruct: true); var modelProvider = new ModelProvider(inputModel); var codeFile = new TypeProviderWriter(modelProvider).Write(); diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/tspCodeModel.json b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/tspCodeModel.json index 7ef39e2f16..94767189aa 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/tspCodeModel.json +++ b/packages/http-client-csharp/generator/TestProjects/Local/Unbranded-TypeSpec/tspCodeModel.json @@ -373,11 +373,11 @@ "Models": [ { "$id": "60", - "Kind": "Model", + "Kind": "model", "Name": "Thing", "Namespace": "UnbrandedTypeSpec", - "Description": "A model with a few properties of literal types", "Usage": "RoundTrip", + "Description": "A model with a few properties of literal types", "Properties": [ { "$id": "61", @@ -608,11 +608,11 @@ }, { "$id": "97", - "Kind": "Model", + "Kind": "model", "Name": "RoundTripModel", "Namespace": "UnbrandedTypeSpec", - "Description": "this is a roundtrip model", "Usage": "RoundTrip", + "Description": "this is a roundtrip model", "Properties": [ { "$id": "98", @@ -931,11 +931,11 @@ "Description": "this is a model with required nullable properties", "Type": { "$id": "144", - "Kind": "Model", + "Kind": "model", "Name": "ModelWithRequiredNullableProperties", "Namespace": "UnbrandedTypeSpec", - "Description": "A model with a few required nullable properties", "Usage": "RoundTrip", + "Description": "A model with a few required nullable properties", "Properties": [ { "$id": "145", @@ -1008,11 +1008,11 @@ }, { "$id": "154", - "Kind": "Model", + "Kind": "model", "Name": "Friend", "Namespace": "UnbrandedTypeSpec", - "Description": "this is not a friendly model but with a friendly name", "Usage": "RoundTrip", + "Description": "this is not a friendly model but with a friendly name", "Properties": [ { "$id": "155", @@ -1030,11 +1030,11 @@ }, { "$id": "157", - "Kind": "Model", + "Kind": "model", "Name": "ProjectedModel", "Namespace": "UnbrandedTypeSpec", - "Description": "this is a model with a projected name", "Usage": "RoundTrip", + "Description": "this is a model with a projected name", "Properties": [ { "$id": "158", @@ -1052,7 +1052,7 @@ }, { "$id": "160", - "Kind": "Model", + "Kind": "model", "Name": "ReturnsAnonymousModelResponse", "Namespace": "UnbrandedTypeSpec", "Usage": "Output",