Files
2026-08-27 10:56:38 -06:00

104 lines
2.6 KiB
C#

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp;
internal sealed class FileIdentifier
{
private class FileIdentifierData(string? encoderFallbackErrorMessage, string displayFilePath, ImmutableArray<byte> filePathChecksumOpt)
{
public readonly string? EncoderFallbackErrorMessage = encoderFallbackErrorMessage;
public readonly string DisplayFilePath = displayFilePath;
public readonly ImmutableArray<byte> FilePathChecksumOpt = filePathChecksumOpt;
}
private static readonly Encoding s_encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
private readonly string _filePath;
private FileIdentifierData? _data;
public string DisplayFilePath
{
get
{
EnsureInitialized();
return _data.DisplayFilePath;
}
}
public string? EncoderFallbackErrorMessage
{
get
{
EnsureInitialized();
return _data.EncoderFallbackErrorMessage;
}
}
public ImmutableArray<byte> FilePathChecksumOpt
{
get
{
EnsureInitialized();
return _data.FilePathChecksumOpt;
}
}
private FileIdentifier(string filePath)
{
_filePath = filePath;
}
private FileIdentifier(ImmutableArray<byte> filePathChecksumOpt, string displayFilePath)
{
_data = new FileIdentifierData(null, displayFilePath, filePathChecksumOpt);
_filePath = string.Empty;
}
[MemberNotNull("_data")]
private void EnsureInitialized()
{
if (_data != null)
{
return;
}
string encoderFallbackErrorMessage = null;
ImmutableArray<byte> filePathChecksumOpt = default(ImmutableArray<byte>);
try
{
byte[] bytes = s_encoding.GetBytes(_filePath);
using HashAlgorithm hashAlgorithm = SourceHashAlgorithms.CreateDefaultInstance();
filePathChecksumOpt = ((IEnumerable<byte>)hashAlgorithm.ComputeHash(bytes)).ToImmutableArray();
}
catch (EncoderFallbackException ex)
{
encoderFallbackErrorMessage = ex.Message;
}
string displayFilePath = GeneratedNames.GetDisplayFilePath(_filePath);
_data = new FileIdentifierData(encoderFallbackErrorMessage, displayFilePath, filePathChecksumOpt);
}
public static FileIdentifier Create(SyntaxTree tree)
{
return Create(tree.FilePath);
}
public static FileIdentifier Create(string filePath)
{
return new FileIdentifier(filePath);
}
public static FileIdentifier Create(ImmutableArray<byte> filePathChecksumOpt, string displayFilePath)
{
return new FileIdentifier(filePathChecksumOpt, displayFilePath);
}
}