using System;
using System.Collections.Generic;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace StardewModdingAPI.Framework.ModLoading.Symbols
{
/// Provides assembly symbol readers for Mono.Cecil.
internal class SymbolReaderProvider : ISymbolReaderProvider
{
/*********
** Fields
*********/
/// The underlying symbol reader provider.
private readonly ISymbolReaderProvider BaseProvider = new DefaultSymbolReaderProvider(throwIfNoSymbol: false);
/// The symbol data loaded by absolute assembly path.
private readonly Dictionary SymbolsByAssemblyPath = new(StringComparer.OrdinalIgnoreCase);
/*********
** Public methods
*********/
/// Add the symbol file for a given assembly name, if it's not already registered.
/// The assembly file name.
/// Get the raw file stream for the symbols.
public void TryAddSymbolData(string fileName, Func getSymbolStream)
{
if (!this.SymbolsByAssemblyPath.ContainsKey(fileName))
this.SymbolsByAssemblyPath.Add(fileName, getSymbolStream());
}
/// Get a symbol reader for a given module and assembly name.
/// The loaded assembly module.
/// The assembly file name.
public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName)
{
return this.SymbolsByAssemblyPath.TryGetValue(module.Name, out Stream? symbolData)
? new SymbolReader(module, symbolData)
: this.BaseProvider.GetSymbolReader(module, fileName);
}
/// Get a symbol reader for a given module and symbol stream.
/// The loaded assembly module.
/// The loaded symbol file stream.
public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream)
{
return this.SymbolsByAssemblyPath.TryGetValue(module.Name, out Stream? symbolData)
? new SymbolReader(module, symbolData)
: this.BaseProvider.GetSymbolReader(module, symbolStream);
}
}
}