File: DocumentationComments\DocumentationCommentIncludeCache.cs
Web Access
Project: src\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis
{
    internal sealed class DocumentationCommentIncludeCache : CachingFactory<string, KeyValuePair<string, XDocument>>
    {
        // TODO: tune
        private const int Size = 5;
 
        /// <summary>
        /// WARN: This is a test hook - do not take a dependency on this.
        /// </summary>
        internal static int CacheMissCount { get; private set; }
 
        public DocumentationCommentIncludeCache(XmlReferenceResolver resolver)
            : base(Size,
                   key => MakeValue(resolver, key),
                   KeyHashCode,
                   KeyValueEquality)
        {
            CacheMissCount = 0;
        }
 
        public XDocument GetOrMakeDocument(string resolvedPath)
        {
            return GetOrMakeValue(resolvedPath).Value;
        }
 
        private static readonly XmlReaderSettings s_xmlSettings = new XmlReaderSettings()
        {
            // Dev12 prohibits DTD
            DtdProcessing = DtdProcessing.Prohibit
        };
 
        /// <exception cref="IOException"></exception>
        /// <exception cref="XmlException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        private static KeyValuePair<string, XDocument> MakeValue(XmlReferenceResolver resolver, string resolvedPath)
        {
            CacheMissCount++;
 
            using (Stream stream = resolver.OpenReadChecked(resolvedPath))
            {
                using (XmlReader reader = XmlReader.Create(stream, s_xmlSettings))
                {
                    var document = XDocument.Load(reader, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
                    return KeyValuePairUtil.Create(resolvedPath, document);
                }
            }
        }
 
        private static int KeyHashCode(string resolvedPath)
        {
            return resolvedPath.GetHashCode();
        }
 
        private static bool KeyValueEquality(string resolvedPath, KeyValuePair<string, XDocument> pathAndDocument)
        {
            return resolvedPath == pathAndDocument.Key;
        }
    }
}