private bool TryGetAttributeProperties()

in sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs [613:676]


            private bool TryGetAttributeProperties(AttributeData attributeData, Location? attribLocation, out IDictionary<string, object?>? attrProperties)
            {
                attrProperties = new Dictionary<string, object?>();

                if (attributeData.ConstructorArguments.Any())
                {
                    if (!TryLoadConstructorArguments(attributeData, attrProperties, attribLocation))
                    {
                        attrProperties = null;
                        return false;
                    }
                }

                foreach (var namedArgument in attributeData.NamedArguments)
                {
                    if (IsArrayOrNotNull(namedArgument.Value))
                    {
                        if (string.Equals(namedArgument.Key, Constants.FunctionMetadataBindingProps.IsBatchedKey)
                            && !attrProperties.ContainsKey("cardinality") && namedArgument.Value.Value != null)
                        {
                            var argValue = (bool)namedArgument.Value.Value; // isBatched only takes in booleans and the generator will parse it as a bool so we can type cast this to use in the next line

                            attrProperties["cardinality"] = argValue ? "Many" : "One";
                        }
                        else
                        {
                            if (TryParseValueByType(namedArgument.Value, out object? argValue))
                            {
                                attrProperties[namedArgument.Key] = argValue;
                            }
                            else
                            {
                                _context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.InvalidBindingAttributeArgument, attribLocation));
                                return false;
                            }
                        }
                    }
                }

                // some properties have default values, so if these properties were not already defined in constructor or named arguments, we will auto-add them here
                foreach (var member in attributeData.AttributeClass!.GetMembers().Where(a => a is IPropertySymbol))
                {
                    var defaultValAttrList = member.GetAttributes().Where(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, _knownFunctionMetadataTypes.DefaultValue));

                    if (defaultValAttrList.SingleOrDefault() is { } defaultValAttr) // list will only be of size one b/c there cannot be duplicates of an attribute on one piece of syntax
                    {
                        var argName = member.Name;
                        object arg = defaultValAttr.ConstructorArguments.SingleOrDefault().Value!; // only one constructor arg in DefaultValue attribute (the default value)
                        if (arg is bool b && string.Equals(argName, Constants.FunctionMetadataBindingProps.IsBatchedKey))
                        {
                            if (!attrProperties.Keys.Contains("cardinality"))
                            {
                                attrProperties["cardinality"] = b ? "Many" : "One";
                            }
                        }
                        else if (!attrProperties.Keys.Any(a => string.Equals(a, argName, StringComparison.OrdinalIgnoreCase))) // check if this property has been assigned a value already in constructor or named args
                        {
                            attrProperties[argName] = arg;
                        }
                    }
                }

                return true;
            }