Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 57 additions & 27 deletions packages/http-client-csharp/emitter/src/lib/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,40 +128,70 @@ export function fromSdkModelType(
.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)
);
fromSdkModelProperty(
p,
{
ModelName: inputModelType?.Name,
Namespace: inputModelType?.Namespace,
} as LiteralTypeContext,
[]
)
)
.flat();
}

return inputModelType;

function fromSdkModelProperty(
propertyType: SdkModelPropertyType,
literalTypeContext: LiteralTypeContext
): InputModelProperty {
const serializedName =
propertyType.kind === "property"
? (propertyType as SdkBodyModelPropertyType).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 modelProperty: InputModelProperty = {
Name: propertyType.name,
SerializedName: serializedName,
Description: propertyType.description ?? (isDiscriminator ? "Discriminator" : ""),
Type: fromSdkType(propertyType.type, context, models, enums, literalTypeContext),
IsRequired: isRequired,
IsReadOnly: propertyType.kind === "property" && isReadOnly(propertyType),
IsDiscriminator: isDiscriminator === true ? true : undefined, // TODO: keep backward compatible to ease comparison. remove this after TCGC is merged
};
literalTypeContext: LiteralTypeContext,
flattenedNamePrefixes: string[]
): InputModelProperty[] {
if (propertyType.kind !== "property" || !propertyType.flatten) {
const serializedName =
propertyType.kind === "property"
? (propertyType as SdkBodyModelPropertyType).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 modelProperty: InputModelProperty = {
Name: propertyType.name,
SerializedName: serializedName,
Description: propertyType.description ?? (isDiscriminator ? "Discriminator" : ""),
Type: fromSdkType(propertyType.type, context, models, enums, literalTypeContext),
IsRequired: isRequired,
IsReadOnly: propertyType.kind === "property" && isReadOnly(propertyType),
IsDiscriminator: isDiscriminator === true ? true : undefined,
FlattenedNames:
flattenedNamePrefixes.length > 0
? flattenedNamePrefixes.concat(propertyType.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
)
);
}

return modelProperty;
return flattenedProperties;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface InputModelProperty {
IsRequired: boolean;
IsReadOnly: boolean;
IsDiscriminator?: boolean;
FlattenedNames?: string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ op test(@body input: Pet): Pet;
IsReadOnly: false,
IsDiscriminator: true,
Description: "Discriminator",
FlattenedNames: undefined,
} as InputModelProperty,
discriminatorProperty
);
Expand Down Expand Up @@ -188,6 +189,7 @@ op test(@body input: Pet): Pet;
IsRequired: true,
IsReadOnly: false,
IsDiscriminator: true,
FlattenedNames: undefined,
} as InputModelProperty,
discriminatorProperty
);
Expand Down Expand Up @@ -312,6 +314,7 @@ op test(@body input: Pet): Pet;
IsRequired: true,
IsReadOnly: false,
IsDiscriminator: true,
FlattenedNames: undefined,
} as InputModelProperty,
discriminatorProperty
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;

namespace Microsoft.Generator.CSharp.Input
{
public class InputModelProperty
{
public InputModelProperty(string name, string serializedName, string description, InputType type, bool isRequired, bool isReadOnly, bool isDiscriminator)
public InputModelProperty(string name, string serializedName, string description, InputType type, bool isRequired, bool isReadOnly, bool isDiscriminator, IReadOnlyList<string>? flattenedNames = null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need flatten feature in non-branded SDK?

{
Name = name;
SerializedName = serializedName;
Expand All @@ -14,6 +16,7 @@ public InputModelProperty(string name, string serializedName, string description
IsRequired = isRequired;
IsReadOnly = isReadOnly;
IsDiscriminator = isDiscriminator;
FlattenedNames = flattenedNames;
}

public string Name { get; }
Expand All @@ -23,5 +26,6 @@ public InputModelProperty(string name, string serializedName, string description
public bool IsRequired { get; }
public bool IsReadOnly { get; }
public bool IsDiscriminator { get; }
public IReadOnlyList<string>? FlattenedNames { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

Expand Down Expand Up @@ -31,6 +32,7 @@ private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader read
bool isReadOnly = false;
bool isRequired = false;
bool isDiscriminator = false;
IReadOnlyList<string>? flattenedNames = null;

while (reader.TokenType != JsonTokenType.EndObject)
{
Expand All @@ -41,7 +43,8 @@ private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader read
|| reader.TryReadWithConverter(nameof(InputModelProperty.Type), options, ref propertyType)
|| reader.TryReadBoolean(nameof(InputModelProperty.IsReadOnly), ref isReadOnly)
|| reader.TryReadBoolean(nameof(InputModelProperty.IsRequired), ref isRequired)
|| reader.TryReadBoolean(nameof(InputModelProperty.IsDiscriminator), ref isDiscriminator);
|| reader.TryReadBoolean(nameof(InputModelProperty.IsDiscriminator), ref isDiscriminator)
|| reader.TryReadStringArray(nameof(InputModelProperty.FlattenedNames), ref flattenedNames);

if (!isKnownProperty)
{
Expand All @@ -55,7 +58,7 @@ private static InputModelProperty ReadInputModelProperty(ref Utf8JsonReader read
// description = BuilderHelpers.EscapeXmlDocDescription(description);
propertyType = propertyType ?? throw new JsonException($"{nameof(InputModelProperty)} must have a property type.");

var property = new InputModelProperty(name, serializedName ?? name, description, propertyType, isRequired, isReadOnly, isDiscriminator);
var property = new InputModelProperty(name, serializedName ?? name, description, propertyType, isRequired, isReadOnly, isDiscriminator, flattenedNames);
if (id != null)
{
resolver.AddReference(id, property);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,37 @@ public static bool TryReadWithConverter<T>(this ref Utf8JsonReader reader, strin
return result;
}

public static bool TryReadStringArray(this ref Utf8JsonReader reader, string propertyName, ref IReadOnlyList<string>? value)
{
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}

if (reader.GetString() != propertyName)
{
return false;
}

reader.Read();

if (reader.TokenType != JsonTokenType.StartArray)
{
throw new JsonException();
}
reader.Read();

var result = new List<string>();
while (reader.TokenType != JsonTokenType.EndArray)
{
result.Add(reader.GetString() ?? throw new JsonException());
reader.Read();
}
reader.Read();
value = result;
return true;
}

public static void SkipProperty(this ref Utf8JsonReader reader)
{
if (reader.TokenType != JsonTokenType.PropertyName)
Expand Down