From 776111de59b567ef586114e18cede66c5fd4bbb2 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 17 Nov 2020 08:07:18 -0500 Subject: [PATCH] Avoid unnecessary LINQ and string joins in JsonConfigurationFileParser --- .../src/JsonConfigurationFileParser.cs | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/src/JsonConfigurationFileParser.cs b/src/libraries/Microsoft.Extensions.Configuration.Json/src/JsonConfigurationFileParser.cs index 17d8ea4a60f591..d8cdbc4438ad31 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/src/JsonConfigurationFileParser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/src/JsonConfigurationFileParser.cs @@ -3,27 +3,24 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; -using System.Linq; using System.Text.Json; namespace Microsoft.Extensions.Configuration.Json { - internal class JsonConfigurationFileParser + internal sealed class JsonConfigurationFileParser { private JsonConfigurationFileParser() { } - private readonly IDictionary _data = new SortedDictionary(StringComparer.OrdinalIgnoreCase); - private readonly Stack _context = new Stack(); - private string _currentPath; + private readonly SortedDictionary _data = new SortedDictionary(StringComparer.OrdinalIgnoreCase); + private readonly Stack _paths = new Stack(); public static IDictionary Parse(Stream input) => new JsonConfigurationFileParser().ParseStream(input); private IDictionary ParseStream(Stream input) { - _data.Clear(); - var jsonDocumentOptions = new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, @@ -55,22 +52,26 @@ private void VisitElement(JsonElement element) ExitContext(); } - if (isEmpty && _currentPath != null) + if (isEmpty && _paths.Count > 0) { - _data[_currentPath] = null; + _data[_paths.Peek()] = null; } } private void VisitValue(JsonElement value) { - switch (value.ValueKind) { + Debug.Assert(_paths.Count > 0); + + switch (value.ValueKind) + { case JsonValueKind.Object: VisitElement(value); break; case JsonValueKind.Array: int index = 0; - foreach (JsonElement arrayElement in value.EnumerateArray()) { + foreach (JsonElement arrayElement in value.EnumerateArray()) + { EnterContext(index.ToString()); VisitValue(arrayElement); ExitContext(); @@ -83,7 +84,7 @@ private void VisitValue(JsonElement value) case JsonValueKind.True: case JsonValueKind.False: case JsonValueKind.Null: - string key = _currentPath; + string key = _paths.Peek(); if (_data.ContainsKey(key)) { throw new FormatException(SR.Format(SR.Error_KeyIsDuplicated, key)); @@ -96,16 +97,11 @@ private void VisitValue(JsonElement value) } } - private void EnterContext(string context) - { - _context.Push(context); - _currentPath = ConfigurationPath.Combine(_context.Reverse()); - } + private void EnterContext(string context) => + _paths.Push(_paths.Count > 0 ? + _paths.Peek() + ConfigurationPath.KeyDelimiter + context : + context); - private void ExitContext() - { - _context.Pop(); - _currentPath = ConfigurationPath.Combine(_context.Reverse()); - } + private void ExitContext() => _paths.Pop(); } }