in sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.CardinalityParser.cs [66:155]
public bool IsCardinalityValid(IParameterSymbol parameterSymbol, AttributeData attribute, out DataType dataType)
{
dataType = DataType.Undefined;
var cardinalityIsNamedArg = false;
// check if IsBatched is defined in the NamedArguments
foreach (var arg in attribute.NamedArguments)
{
if (String.Equals(arg.Key, Constants.FunctionMetadataBindingProps.IsBatchedKey) &&
arg.Value.Value != null)
{
cardinalityIsNamedArg = true;
var isBatched = (bool)arg.Value.Value; // isBatched takes in booleans so we can just type cast it here to use
if (!isBatched)
{
dataType = _dataTypeParser.GetDataType(parameterSymbol.Type);
return true;
}
}
}
// When "IsBatched" is not a named arg, we have to check the default value
if (!cardinalityIsNamedArg)
{
if (!TryGetIsBatchedProp(attribute, out var isBatchedProp))
{
dataType = DataType.Undefined;
return false;
}
var defaultValAttr = isBatchedProp!
.GetAttributes()
.SingleOrDefault(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, _knownFunctionMetadataTypes.DefaultValue));
var defaultVal = defaultValAttr!.ConstructorArguments.SingleOrDefault().Value!.ToString(); // there is only one constructor arg for the DefaultValue attribute (the default value)
if (!bool.TryParse(defaultVal, out bool b) || !b)
{
dataType = _dataTypeParser.GetDataType(parameterSymbol.Type);
return true;
}
}
// we check if the param is an array type
// we exclude byte arrays (byte[]) b/c we handle that as Cardinality.One (we handle this similar to how a char[] is basically a string)
if (parameterSymbol.Type is IArrayTypeSymbol && !SymbolEqualityComparer.Default.Equals(parameterSymbol.Type, _knownTypes.ByteArray))
{
dataType = _dataTypeParser.GetDataType(parameterSymbol.Type);
return true;
}
// Check if mapping type - mapping enumerables are not valid types for Cardinality.Many
if (parameterSymbol.Type.IsOrImplementsOrDerivesFrom(_knownTypes.IEnumerableOfKeyValuePair)
|| parameterSymbol.Type.IsOrImplementsOrDerivesFrom(_knownTypes.LookupGeneric)
|| parameterSymbol.Type.IsOrImplementsOrDerivesFrom(_knownTypes.DictionaryGeneric))
{
return false;
}
var isGenericEnumerable = parameterSymbol.Type.IsOrImplementsOrDerivesFrom(_knownTypes.IEnumerableGeneric);
var isEnumerable = parameterSymbol.Type.IsOrImplementsOrDerivesFrom(_knownTypes.IEnumerable);
if (!_dataTypeParser.IsStringType(parameterSymbol.Type) && (isGenericEnumerable || isEnumerable))
{
if (_dataTypeParser.IsStringType(parameterSymbol.Type))
{
dataType = DataType.String;
}
else if (_dataTypeParser.IsBinaryType(parameterSymbol.Type))
{
dataType = DataType.Binary;
}
else if (isGenericEnumerable)
{
dataType = ResolveIEnumerableOfT(parameterSymbol, out bool hasError);
if (hasError)
{
return false;
}
return true;
}
return true;
}
// trigger input type doesn't match any of the valid cases so return false
return false;
}