File: Parsing\AttributeProcessors.cs
Web Access
Project: src\src\Generators\Microsoft.Gen.Logging\Microsoft.Gen.Logging.csproj (Microsoft.Gen.Logging)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using Microsoft.CodeAnalysis;
 
namespace Microsoft.Gen.Logging.Parsing;
 
internal static class AttributeProcessors
{
    private const string MessageProperty = "Message";
    private const string EventNameProperty = "EventName";
    private const string EventIdProperty = "EventId";
    private const string LevelProperty = "Level";
    private const string SkipEnabledCheckProperty = "SkipEnabledCheck";
    private const string SkipNullProperties = "SkipNullProperties";
    private const string OmitReferenceName = "OmitReferenceName";
    private const string Transitive = "Transitive";
 
    private const int LogLevelError = 4;
    private const int LogLevelCritical = 5;
 
    public static (int? eventId, int? level, string message, string? eventName, bool skipEnabledCheck)
        ExtractLoggerMessageAttributeValues(AttributeData attr, SymbolHolder symbols)
    {
        // Five constructor arg shapes:
        //
        //   ()
        //   (int eventId, LogLevel level, string message)
        //   (LogLevel level, string message)
        //   (LogLevel level)
        //   (string message)
 
        int? eventId = null;
        int? level = null;
        string? eventName = null;
        string message = string.Empty;
        bool skipEnabledCheck = false;
        bool useDefaultForSkipEnabledCheck = true;
 
        foreach (var a in attr.ConstructorArguments)
        {
            if (SymbolEqualityComparer.Default.Equals(a.Type, symbols.LogLevelSymbol))
            {
                var v = a.Value;
                if (v is int l)
                {
                    level = l;
                }
            }
            else if (a.Type?.SpecialType == SpecialType.System_Int32)
            {
                var v = a.Value;
                if (v is int l)
                {
                    eventId = l;
                }
            }
            else
            {
                message = a.Value as string ?? string.Empty;
            }
        }
 
        foreach (var a in attr.NamedArguments)
        {
            var v = a.Value.Value;
            if (v != null)
            {
                switch (a.Key)
                {
                    case MessageProperty:
                        if (v is string m)
                        {
                            message = m;
                        }
 
                        break;
 
                    case EventNameProperty:
                        if (v is string e)
                        {
                            eventName = e;
                        }
 
                        break;
 
                    case LevelProperty:
                        if (v is int l)
                        {
                            level = l;
                        }
 
                        break;
 
                    case EventIdProperty:
                        if (v is int id)
                        {
                            eventId = id;
                        }
 
                        break;
 
                    case SkipEnabledCheckProperty:
                        if (v is bool b)
                        {
                            skipEnabledCheck = b;
                            useDefaultForSkipEnabledCheck = false;
                        }
 
                        break;
                }
            }
        }
 
        if (level != null)
        {
            if (useDefaultForSkipEnabledCheck && (level == LogLevelError || level == LogLevelCritical))
            {
                // unless explicitly set by the user, by default we disable the Enabled check when the log level is Error or Critical
                skipEnabledCheck = true;
            }
        }
 
        return (eventId, level, message, eventName, skipEnabledCheck);
    }
 
    public static (bool skipNullProperties, bool omitReferenceName, bool transitive) ExtractLogPropertiesAttributeValues(AttributeData attr)
    {
        bool skipNullProperties = false;
        bool omitReferenceName = false;
        bool transitive = false;
 
        foreach (var a in attr.NamedArguments)
        {
            var v = a.Value.Value;
            if (v != null)
            {
                if (a.Key == SkipNullProperties)
                {
                    if (v is bool b)
                    {
                        skipNullProperties = b;
                    }
                }
                else if (a.Key == OmitReferenceName)
                {
                    if (v is bool b)
                    {
                        omitReferenceName = b;
                    }
                }
                else if (a.Key == Transitive)
                {
                    if (v is bool b)
                    {
                        transitive = b;
                    }
                }
            }
        }
 
        return (skipNullProperties, omitReferenceName, transitive);
    }
 
    public static (bool omitReferenceName, ITypeSymbol providerType, string providerMethodName) ExtractTagProviderAttributeValues(AttributeData attr)
    {
        bool omitReferenceName = false;
        ITypeSymbol? providerType = null;
        string? providerMethodName = null;
 
        foreach (var a in attr.NamedArguments)
        {
            var v = a.Value.Value;
            if (v != null)
            {
                if (a.Key == OmitReferenceName)
                {
                    if (v is bool b)
                    {
                        omitReferenceName = b;
                    }
                }
            }
        }
 
        providerType = attr.ConstructorArguments[0].Value as ITypeSymbol;
        providerMethodName = attr.ConstructorArguments[1].Value as string;
 
        return (omitReferenceName, providerType!, providerMethodName!);
    }
 
    public static string ExtractTagNameAttributeValues(AttributeData attr)
        => attr.ConstructorArguments[0].Value as string ?? string.Empty;
}