File: StringMarshallingInfoProvider.cs
Web Access
Project: src\src\libraries\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj (Microsoft.Interop.SourceGeneration)
// 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.Interop
{
    /// <summary>
    /// This class supports generating marshalling info for the <see cref="string"/> type.
    /// This includes support for the <c>System.Runtime.InteropServices.StringMarshalling</c> enum.
    /// </summary>
    public sealed class StringMarshallingInfoProvider : ITypeBasedMarshallingInfoProvider
    {
        private readonly Compilation _compilation;
        private readonly GeneratorDiagnosticsBag _diagnostics;
        private readonly AttributeData _stringMarshallingCustomAttribute;
        private readonly DefaultMarshallingInfo _defaultMarshallingInfo;
 
        public StringMarshallingInfoProvider(Compilation compilation, GeneratorDiagnosticsBag diagnostics, AttributeData stringMarshallingCustomAttribute, DefaultMarshallingInfo defaultMarshallingInfo)
        {
            _compilation = compilation;
            _diagnostics = diagnostics;
            _stringMarshallingCustomAttribute = stringMarshallingCustomAttribute;
            _defaultMarshallingInfo = defaultMarshallingInfo;
        }
 
        public bool CanProvideMarshallingInfoForType(ITypeSymbol type) => type.SpecialType == SpecialType.System_String;
 
        public MarshallingInfo GetMarshallingInfo(ITypeSymbol type, int indirectionDepth, UseSiteAttributeProvider useSiteAttributes, GetMarshallingInfoCallback marshallingInfoCallback)
        {
            if (_defaultMarshallingInfo.CharEncoding == CharEncoding.Undefined)
            {
                return NoMarshallingInfo.Instance;
            }
            else if (_defaultMarshallingInfo.CharEncoding == CharEncoding.Custom)
            {
                if (_defaultMarshallingInfo.StringMarshallingCustomType is not null)
                {
                    CountInfo countInfo = NoCountInfo.Instance;
                    if (useSiteAttributes.TryGetUseSiteAttributeInfo(indirectionDepth, out var useSiteInfo))
                    {
                        countInfo = useSiteInfo.CountInfo;
                    }
                    return CustomMarshallingInfoHelper.CreateNativeMarshallingInfo(
                        type,
                        _defaultMarshallingInfo.StringMarshallingCustomType,
                        _stringMarshallingCustomAttribute,
                        useSiteAttributes,
                        marshallingInfoCallback,
                        indirectionDepth,
                        countInfo,
                        _diagnostics,
                        _compilation);
                }
            }
            else
            {
                // No marshalling info was computed, but a character encoding was provided.
                return _defaultMarshallingInfo.CharEncoding switch
                {
                    CharEncoding.Utf16 => CustomMarshallingInfoHelper.CreateMarshallingInfoByMarshallerTypeName(_compilation, type, TypeNames.Utf16StringMarshaller),
                    CharEncoding.Utf8 => CustomMarshallingInfoHelper.CreateMarshallingInfoByMarshallerTypeName(_compilation, type, TypeNames.Utf8StringMarshaller),
                    _ => throw new InvalidOperationException()
                };
            }
 
            return new MarshallingInfoStringSupport(_defaultMarshallingInfo.CharEncoding);
        }
    }
}