Skip to content

Commit

Permalink
Refine mgmt reference type (#4663)
Browse files Browse the repository at this point in the history
  • Loading branch information
live1206 committed May 10, 2024
1 parent 27913c2 commit b2aadea
Show file tree
Hide file tree
Showing 73 changed files with 82 additions and 6,362 deletions.
3 changes: 2 additions & 1 deletion src/AutoRest.CSharp/Common/Generation/Writers/ModelWriter.cs
Expand Up @@ -10,6 +10,7 @@
using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions;
using AutoRest.CSharp.Common.Output.Models.Types;
using AutoRest.CSharp.Generation.Types;
using AutoRest.CSharp.Mgmt.Output;
using AutoRest.CSharp.Output.Models;
using AutoRest.CSharp.Output.Models.Types;
using Microsoft.CodeAnalysis;
Expand Down Expand Up @@ -123,7 +124,7 @@ private void WriteFieldModifiers(CodeWriter writer, FieldModifiers modifiers)
private void WriteProperty(CodeWriter writer, ObjectTypeProperty property, ObjectType objectType)
{
writer.WriteXmlDocumentationSummary(CreatePropertyDescription(property));
if (Configuration.EnableBicepSerialization && objectType.Declaration.Accessibility == "public" && property.Declaration.Accessibility == "public")
if (!MgmtReferenceType.IsReferenceType(objectType) && Configuration.EnableBicepSerialization && objectType.Declaration.Accessibility == "public" && property.Declaration.Accessibility == "public")
{
writer.Line($"[WirePath(\"{property.GetWirePath()}\")]");
}
Expand Down
10 changes: 0 additions & 10 deletions src/AutoRest.CSharp/Common/Input/CodeModelPartials.cs
Expand Up @@ -124,16 +124,6 @@ public string[] Formats

public bool SkipEncoding => TryGetValue("x-ms-skip-url-encoding", out var value) && Convert.ToBoolean(value);

public bool MgmtReferenceType => TryGetValue("x-ms-mgmt-referenceType", out var value) && Convert.ToBoolean(value);

public bool MgmtPropertyReferenceType => TryGetValue("x-ms-mgmt-propertyReferenceType", out var value) && Convert.ToBoolean(value);

/// <summary>
/// Indicate whether the definition has property <c>x-ms-mgmt-typeReferenceType</c> defined as <c>true</c>.
/// See: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/resourcemanager/Azure.ResourceManager/src/autorest.md
/// </summary>
public bool MgmtTypeReferenceType => TryGetValue("x-ms-mgmt-typeReferenceType", out var value) && Convert.ToBoolean(value);

public string? Format
{
get
Expand Down
Expand Up @@ -17,9 +17,9 @@
using AutoRest.CSharp.Input;
using AutoRest.CSharp.Input.Source;
using AutoRest.CSharp.Mgmt.AutoRest;
using AutoRest.CSharp.Mgmt.Output;
using AutoRest.CSharp.Output.Builders;
using AutoRest.CSharp.Output.Models.Requests;
using AutoRest.CSharp.Output.Models.Serialization;
using AutoRest.CSharp.Output.Models.Serialization.Bicep;
using AutoRest.CSharp.Output.Models.Serialization.Json;
using AutoRest.CSharp.Output.Models.Serialization.Xml;
Expand Down Expand Up @@ -76,7 +76,7 @@ protected SchemaObjectType(ObjectSchema objectSchema, string defaultNamespace, T
IsUnknownDerivedType = objectSchema.IsUnknownDiscriminatorModel;
// we skip the init ctor when there is an extension telling us to, or when this is an unknown derived type in a discriminated set
SkipInitializerConstructor = ObjectSchema is { Extensions.SkipInitCtor: true } || IsUnknownDerivedType;
IsInheritableCommonType = ObjectSchema is { Extensions: { } extensions } && (extensions.MgmtReferenceType || extensions.MgmtTypeReferenceType);
IsInheritableCommonType = MgmtReferenceType.IsTypeReferenceType(ObjectSchema) || MgmtReferenceType.IsReferenceType(ObjectSchema);

JsonConverter = _usage.HasFlag(SchemaTypeUsage.Converter) ? new JsonConverterProvider(this, _sourceInputModel) : null;
}
Expand All @@ -91,7 +91,7 @@ protected SchemaObjectType(ObjectSchema objectSchema, string defaultNamespace, T
private bool _hasCalculatedDefaultDerivedType;
public SerializableObjectType? DefaultDerivedType => _defaultDerivedType ??= BuildDefaultDerivedType();

protected override bool IsAbstract => !Configuration.SuppressAbstractBaseClasses.Contains(DefaultName) && ObjectSchema.Discriminator?.All != null && ObjectSchema.DiscriminatorValue == null;
protected override bool IsAbstract => MgmtReferenceType.IsReferenceType(ObjectSchema) || (!Configuration.SuppressAbstractBaseClasses.Contains(DefaultName) && ObjectSchema.Discriminator?.All != null && ObjectSchema.DiscriminatorValue == null);

public override ObjectTypeProperty? AdditionalPropertiesProperty
{
Expand Down Expand Up @@ -755,7 +755,7 @@ protected override bool EnsureIncludeDeserializer()

protected override JsonObjectSerialization? BuildJsonSerialization()
{
return _supportedSerializationFormats.Contains(KnownMediaType.Json) ? _serializationBuilder.BuildJsonObjectSerialization(ObjectSchema, this) : null;
return MgmtReferenceType.IsReferenceType(ObjectSchema) ? null: _supportedSerializationFormats.Contains(KnownMediaType.Json) ? _serializationBuilder.BuildJsonObjectSerialization(ObjectSchema, this) : null;
}

protected override BicepObjectSerialization? BuildBicepSerialization(JsonObjectSerialization? json)
Expand Down
3 changes: 1 addition & 2 deletions src/AutoRest.CSharp/Mgmt/AutoRest/MgmtOutputLibrary.cs
Expand Up @@ -5,7 +5,6 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using AutoRest.CSharp.Common.Input;
using AutoRest.CSharp.Common.Output.Builders;
using AutoRest.CSharp.Generation.Types;
Expand Down Expand Up @@ -820,7 +819,7 @@ public IEnumerable<Resource> FindResources(ResourceData resourceData)
private TypeProvider BuildModel(Schema schema) => schema switch
{
SealedChoiceSchema or ChoiceSchema => new EnumType(_schemaToInputEnumMap[schema], schema, MgmtContext.Context),
ObjectSchema objectSchema => schema.Extensions != null && (schema.Extensions.MgmtReferenceType || schema.Extensions.MgmtPropertyReferenceType || schema.Extensions.MgmtTypeReferenceType)
ObjectSchema objectSchema => (MgmtReferenceType.IsPropertyReferenceType(schema) || MgmtReferenceType.IsTypeReferenceType(schema) || MgmtReferenceType.IsReferenceType(schema))
? new MgmtReferenceType(objectSchema)
: new MgmtObjectType(objectSchema),
_ => throw new NotImplementedException($"Unhandled schema type {schema.GetType()} with name {schema.Name}")
Expand Down
7 changes: 0 additions & 7 deletions src/AutoRest.CSharp/Mgmt/AutoRest/MgmtTarget.cs
Expand Up @@ -293,13 +293,6 @@ private static void WriteArmModel(GeneratedCodeWorkspace project, TypeProvider m

AddGeneratedFile(project, modelFileName, codeWriter.ToString());

if (model is MgmtReferenceType mgmtReferenceType)
{
var extensions = mgmtReferenceType.ObjectSchema.Extensions;
if (extensions != null && extensions.MgmtReferenceType)
return;
}

WriteSerialization(project, model, serializeWriter, serializationFileName);
}

Expand Down
27 changes: 18 additions & 9 deletions src/AutoRest.CSharp/Mgmt/Generation/ReferenceTypeWriter.cs
Expand Up @@ -15,23 +15,32 @@ protected override void AddClassAttributes(CodeWriter writer, ObjectType objectT
{
if (objectType is not SchemaObjectType schema)
return;
var extensions = schema.ObjectSchema.Extensions;
if (extensions != null)

if (MgmtReferenceType.IsPropertyReferenceType(schema.ObjectSchema))
{
if (Configuration.IsBranded)
writer.UseNamespace("Azure.Core");
if (extensions.MgmtReferenceType)
{
writer.Line($"[{ReferenceClassFinder.ReferenceTypeAttribute}]");
writer.UseNamespace("Azure.Core");
}
else if (extensions.MgmtPropertyReferenceType)
writer.Line($"[{ReferenceClassFinder.PropertyReferenceTypeAttribute}]");
}
else if (MgmtReferenceType.IsTypeReferenceType(schema.ObjectSchema))
{
if (Configuration.IsBranded)
{
writer.Line($"[{ReferenceClassFinder.PropertyReferenceTypeAttribute}]");
writer.UseNamespace("Azure.Core");
}
else if (extensions.MgmtTypeReferenceType)
writer.Line($"[{ReferenceClassFinder.TypeReferenceTypeAttribute}]");
}
else if (MgmtReferenceType.IsReferenceType(schema.ObjectSchema))
{
if (Configuration.IsBranded)
{
writer.Line($"[{ReferenceClassFinder.TypeReferenceTypeAttribute}]");
writer.UseNamespace("Azure.Core");
}

// The hard-coded string input is needed for ReferenceTypeAttribute to work, and this only applies to ResourceData and TrackedResourceData now.
writer.Line($"[{ReferenceClassFinder.ReferenceTypeAttribute}(new string[]{{\"SystemData\"}})]");
}
}

Expand Down
67 changes: 57 additions & 10 deletions src/AutoRest.CSharp/Mgmt/Output/MgmtReferenceType.cs
@@ -1,8 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Linq;
using System.Collections.Generic;
using AutoRest.CSharp.Common.Input;
using AutoRest.CSharp.Generation.Types;
using AutoRest.CSharp.Input;
Expand All @@ -14,23 +13,74 @@ namespace AutoRest.CSharp.Mgmt.Output
{
internal class MgmtReferenceType : MgmtObjectType
{
private static HashSet<string> PropertyReferenceTypeModels = new HashSet<string>
{
"Azure.ResourceManager.Models.ArmPlan",
"Azure.ResourceManager.Models.ArmSku",
"Azure.ResourceManager.Models.EncryptionProperties",
"Azure.ResourceManager.Resources.Models.ExtendedLocation",
"Azure.ResourceManager.Models.ManagedServiceIdentity",
"Azure.ResourceManager.Models.KeyVaultProperties",
"Azure.ResourceManager.Resources.ResourceProviderData",
"Azure.ResourceManager.Models.SystemAssignedServiceIdentity",
"Azure.ResourceManager.Models.SystemData",
"Azure.ResourceManager.Models.UserAssignedIdentity",
"Azure.ResourceManager.Resources.Models.WritableSubResource"
};

private static HashSet<string> TypeReferenceTypeModels = new HashSet<string>
{
"Azure.ResourceManager.Models.OperationStatusResult"
};

private static HashSet<string> ReferenceTypeModels = new HashSet<string>
{
"Azure.ResourceManager.Models.ResourceData",
"Azure.ResourceManager.Models.TrackedResourceData"
};

public static bool IsPropertyReferenceType(Schema schema)
=> PropertyReferenceTypeModels.Contains($"{GetNamespace(schema)}.{schema.Language.Default.Name}");

public static bool IsTypeReferenceType(Schema schema)
=> TypeReferenceTypeModels.Contains($"{GetNamespace(schema)}.{schema.Language.Default.Name}");

public static bool IsReferenceType(ObjectType schema)
=> ReferenceTypeModels.Contains($"{schema.Declaration.Namespace}.{schema.Declaration.Name}");

public static bool IsReferenceType(Schema schema)
=> ReferenceTypeModels.Contains($"{GetNamespace(schema)}.{schema.Language.Default.Name}");

private static string GetNamespace(Schema schema)
{
if (!string.IsNullOrEmpty(schema.Extensions?.Namespace))
{
return schema.Extensions.Namespace;
}

if (!string.IsNullOrEmpty(schema.Language.Default.Namespace))
{
return schema.Language.Default.Namespace;
}

return $"{Configuration.Namespace}.Models";
}

public MgmtReferenceType(ObjectSchema objectSchema, string? name = default, string? nameSpace = default) : base(objectSchema, name, nameSpace)
{
JsonConverter = (ObjectSchema.Extensions?.MgmtPropertyReferenceType == true || ObjectSchema.Extensions?.MgmtTypeReferenceType == true) && ObjectSchema.Extensions?.MgmtReferenceType != true
JsonConverter = (IsPropertyReferenceType(objectSchema) || IsTypeReferenceType(ObjectSchema))
? new JsonConverterProvider(this, _sourceInputModel)
: null;
}

protected override bool IsAbstract => !Configuration.SuppressAbstractBaseClasses.Contains(DefaultName) && ObjectSchema.Extensions?.MgmtReferenceType is true;

protected override ObjectTypeProperty CreatePropertyType(ObjectTypeProperty objectTypeProperty)
{
if (objectTypeProperty.ValueType != null && objectTypeProperty.ValueType.IsFrameworkType)
{
var newProperty = ReferenceTypePropertyChooser.GetExactMatchForReferenceType(objectTypeProperty, objectTypeProperty.ValueType.FrameworkType);
if (newProperty != null)
{
string fullSerializedName = this.GetFullSerializedName(objectTypeProperty);
string fullSerializedName = GetFullSerializedName(objectTypeProperty);
MgmtReport.Instance.TransformSection.AddTransformLogForApplyChange(
new TransformItem(TransformTypeName.ReplacePropertyType, fullSerializedName),
fullSerializedName,
Expand All @@ -42,10 +92,7 @@ protected override ObjectTypeProperty CreatePropertyType(ObjectTypeProperty obje
return objectTypeProperty;
}

protected override CSharpType? CreateInheritedType()
{
return ObjectSchema.Extensions?.MgmtReferenceType == true ? CreateInheritedTypeWithNoExtraMatch() : base.CreateInheritedType();
}
protected override CSharpType? CreateInheritedType() => base.CreateInheritedType();

// the reference types do not need raw data field
public override ObjectTypeProperty? RawDataField => null;
Expand Down
4 changes: 0 additions & 4 deletions src/AutoRest.CSharp/Properties/launchSettings.json
Expand Up @@ -432,10 +432,6 @@
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\TestProjects\\MgmtPropertyChooser\\src\\Generated -n"
},
"MgmtReferenceTypes": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\TestProjects\\MgmtReferenceTypes\\src\\Generated -n"
},
"MgmtResourceName": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\TestProjects\\MgmtResourceName\\src\\Generated -n"
Expand Down

This file was deleted.

0 comments on commit b2aadea

Please sign in to comment.