in src/AutoRest.CSharp/Mgmt/AutoRest/MgmtOutputLibrary.cs [132:233]
private IEnumerable<InputType> UpdateBodyParameters()
{
var updatedTypes = new List<InputType>();
Dictionary<string, int> usageCounts = new Dictionary<string, int>();
// run one pass to get the schema usage count
foreach (var client in _inputClients)
{
foreach (var operation in client.Operations)
{
foreach (var parameter in operation.Parameters)
{
if (parameter.Location != RequestLocation.Body)
continue;
IncrementCount(usageCounts, parameter.Type.GetImplementType().Name);
}
foreach (var response in operation.Responses)
{
var responseSchema = response.BodyType;
if (responseSchema is null)
continue;
IncrementCount(usageCounts, responseSchema.GetImplementType().Name);
}
}
}
// run second pass to rename the ones based on the schema usage count
foreach (var client in _inputClients)
{
foreach (var operation in client.Operations)
{
if (operation.HttpMethod != RequestMethod.Patch && operation.HttpMethod != RequestMethod.Put && operation.HttpMethod != RequestMethod.Post)
continue;
var bodyParam = operation.Parameters.FirstOrDefault(p => p.Location == RequestLocation.Body);
if (bodyParam is null)
continue;
if (!usageCounts.TryGetValue(bodyParam.Type.GetImplementType().Name, out var count))
continue;
// get the request path and operation set
RequestPath requestPath = RequestPath.FromOperation(operation, client, MgmtContext.TypeFactory);
var operationSet = RawRequestPathToOperationSets[requestPath];
if (operationSet.TryGetResourceDataSchema(out _, out var resourceDataSchema, _input))
{
// if this is a resource, we need to make sure its body parameter is required when the verb is put or patch
BodyParameterNormalizer.MakeRequired(bodyParam, operation.HttpMethod);
}
if (count != 1)
{
//even if it has multiple uses for a model type we should normalize the param name just not change the type
BodyParameterNormalizer.UpdateParameterNameOnly(bodyParam, ResourceDataSchemaNameToOperationSets, operation);
continue;
}
if (resourceDataSchema is not null)
{
//TODO handle expandable request paths. We assume that this is fine since if all of the expanded
//types use the same model they should have a common name, but since this case doesn't exist yet
//we don't know for sure
if (requestPath.IsExpandable)
throw new InvalidOperationException($"Found expandable path in UpdatePatchParameterNames for {client.Key}.{operation.CSharpName()} : {requestPath}");
var name = GetResourceName(resourceDataSchema.Name, operationSet, requestPath);
BodyParameterNormalizer.Update(operation.HttpMethod, bodyParam, name, operation, updatedTypes);
}
else
{
BodyParameterNormalizer.UpdateUsingReplacement(bodyParam, ResourceDataSchemaNameToOperationSets, operation, updatedTypes);
}
}
}
// run third pass to rename the corresponding parameters
foreach (var client in _inputClients)
{
foreach (var operation in client.Operations)
{
foreach (var param in operation.Parameters)
{
if (param.Location != RequestLocation.Body)
continue;
if (param.Type.GetImplementType() is not InputModelType inputModel)
continue;
string originalName = param.Name;
param.Name = NormalizeParamNames.GetNewName(originalName, inputModel.Name, ResourceDataSchemaNameToOperationSets);
string fullSerializedName = operation.GetFullSerializedName(param);
MgmtReport.Instance.TransformSection.AddTransformLogForApplyChange(
new TransformItem(TransformTypeName.UpdateBodyParameter, fullSerializedName),
fullSerializedName, "SetBodyParameterNameOnThirdPass", originalName, param.Name);
}
}
}
return updatedTypes;
}