in sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs [132:185]
private bool TryGetMethodOutputBinding(IMethodSymbol method, out bool hasMethodOutputBinding, out GeneratorRetryOptions? retryOptions, out IList<IDictionary<string, object>>? bindingsList)
{
var attributes = method!.GetAttributes(); // methodSymbol is not null here because it's checked in IsValidAzureFunction which is called before bindings are collected/created
AttributeData? outputBindingAttribute = null;
hasMethodOutputBinding = false;
retryOptions = null;
foreach (var attribute in attributes)
{
if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass?.BaseType, _knownFunctionMetadataTypes.RetryAttribute))
{
if (TryGetRetryOptionsFromAttribute(attribute, Location.None, out GeneratorRetryOptions? retryOptionsFromAttr))
{
retryOptions = retryOptionsFromAttr;
}
}
if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass?.BaseType, _knownFunctionMetadataTypes.OutputBindingAttribute))
{
// There can only be one method output binding associated with a function. If there is more than one, we return a diagnostic error here.
if (hasMethodOutputBinding)
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.MultipleBindingsGroupedTogether, Location.None, new object[] { "Method", method.Name }));
bindingsList = null;
return false;
}
outputBindingAttribute = attribute;
hasMethodOutputBinding = true;
}
}
if (outputBindingAttribute != null)
{
if (!TryCreateBindingDictionary(outputBindingAttribute, Constants.FunctionMetadataBindingProps.ReturnBindingName, Location.None, out IDictionary<string, object>? bindings))
{
bindingsList = null;
return false;
}
bindingsList = new List<IDictionary<string, object>>(capacity: 1)
{
bindings!
};
return true;
}
// we didn't find any output bindings on the method, but there were no errors
// so we treat the found bindings as an empty list and return true
bindingsList = new List<IDictionary<string, object>>();
return true;
}