Skip to content

Commit ef5bce3

Browse files
authored
Parse the assets file with System.Text.Json (#5627)
Crated a new struct to parse the assets file using System.Text.Json instead of Newtonsoft. It will read the file without loading it completely in memory, reducing memory allocations. PRs associated with this: * Create class for reading Json files in chunks (#5530) * System.Text.Json Migration - Adding code to parse the PackageSpec using STJ (#5541) * System.Text.Json Migration - Adding code to parse the Project.Assets.Json file using STJ. (#5558) * Create class for reading Json files in chunks (#5530)
1 parent 8b658e2 commit ef5bce3

35 files changed

+6681
-1791
lines changed

src/NuGet.Core/NuGet.ProjectModel/DependencyGraphSpec.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.IO;
88
using System.Linq;
99
using Newtonsoft.Json;
10-
using Newtonsoft.Json.Linq;
1110
using NuGet.Common;
1211
using NuGet.Packaging;
1312

@@ -253,7 +252,9 @@ public static DependencyGraphSpec Load(string path)
253252
case "projects":
254253
jsonReader.ReadObject(projectsPropertyName =>
255254
{
255+
#pragma warning disable CS0612 // Type or member is obsolete
256256
PackageSpec packageSpec = JsonPackageSpecReader.GetPackageSpec(jsonReader, name: null, path, EnvironmentVariableWrapper.Instance);
257+
#pragma warning restore CS0612 // Type or member is obsolete
257258
dgspec._projects.Add(projectsPropertyName, packageSpec);
258259
});
259260
break;

src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ internal static FileFormatException Create(Exception exception, int line, int co
8585
return ex.WithFilePath(path).WithLineInfo(line, column);
8686
}
8787

88+
internal static FileFormatException Create(Exception exception, string path)
89+
{
90+
var message = string.Format(CultureInfo.CurrentCulture,
91+
Strings.Log_ErrorReadingProjectJson,
92+
path,
93+
exception.Message);
94+
95+
var ex = new FileFormatException(message, exception);
96+
97+
return ex.WithFilePath(path);
98+
}
99+
88100
public static FileFormatException Create(string message, JToken value, string path)
89101
{
90102
var lineInfo = (IJsonLineInfo)value;
@@ -101,32 +113,24 @@ internal static FileFormatException Create(string message, int line, int column,
101113
return ex.WithFilePath(path).WithLineInfo(line, column);
102114
}
103115

104-
internal static FileFormatException Create(Exception exception, string path)
116+
internal static FileFormatException Create(JsonReaderException exception, string path)
105117
{
106-
var jex = exception as JsonReaderException;
107-
108118
string message;
109-
if (jex == null)
110-
{
111-
message = string.Format(CultureInfo.CurrentCulture,
112-
Strings.Log_ErrorReadingProjectJson,
113-
path,
114-
exception.Message);
115-
116-
return new FileFormatException(message, exception).WithFilePath(path);
117-
}
118-
else
119-
{
120-
message = string.Format(CultureInfo.CurrentCulture,
121-
Strings.Log_ErrorReadingProjectJsonWithLocation,
122-
path, jex.LineNumber,
123-
jex.LinePosition,
124-
exception.Message);
125-
126-
return new FileFormatException(message, exception)
127-
.WithFilePath(path)
128-
.WithLineInfo(jex);
129-
}
119+
message = string.Format(CultureInfo.CurrentCulture,
120+
Strings.Log_ErrorReadingProjectJsonWithLocation,
121+
path, exception.LineNumber,
122+
exception.LinePosition,
123+
exception.Message);
124+
125+
return new FileFormatException(message, exception)
126+
.WithFilePath(path)
127+
.WithLineInfo(exception);
128+
}
129+
130+
internal static FileFormatException Create(string message, string path)
131+
{
132+
return new FileFormatException(message)
133+
.WithFilePath(path);
130134
}
131135
}
132136
}

src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs

Lines changed: 1825 additions & 0 deletions
Large diffs are not rendered by default.

src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919

2020
namespace NuGet.ProjectModel
2121
{
22-
public static class JsonPackageSpecReader
22+
public static partial class JsonPackageSpecReader
2323
{
2424
private static readonly char[] DelimitedStringSeparators = { ' ', ',' };
2525
private static readonly char[] VersionSeparators = new[] { ';' };
26-
26+
private const char VersionSeparator = ';';
2727
public static readonly string RestoreOptions = "restore";
2828
public static readonly string RestoreSettings = "restoreSettings";
2929
public static readonly string HideWarningsAndErrors = "hideWarningsAndErrors";
@@ -49,31 +49,52 @@ public static PackageSpec GetPackageSpec(string json, string name, string packag
4949
}
5050
}
5151

52+
public static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue)
53+
{
54+
return GetPackageSpec(stream, name, packageSpecPath, snapshotValue, EnvironmentVariableWrapper.Instance);
55+
}
56+
5257
[Obsolete("This method is obsolete and will be removed in a future release.")]
5358
public static PackageSpec GetPackageSpec(JObject json)
5459
{
5560
return GetPackageSpec(json, name: null, packageSpecPath: null, snapshotValue: null);
5661
}
5762

58-
public static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue)
63+
[Obsolete("This method is obsolete and will be removed in a future release.")]
64+
public static PackageSpec GetPackageSpec(JObject rawPackageSpec, string name, string packageSpecPath, string snapshotValue)
5965
{
60-
using (var streamReader = new StreamReader(stream))
61-
using (var jsonReader = new JsonTextReader(streamReader))
66+
using (var stringReader = new StringReader(rawPackageSpec.ToString()))
67+
using (var jsonReader = new JsonTextReader(stringReader))
6268
{
6369
return GetPackageSpec(jsonReader, name, packageSpecPath, EnvironmentVariableWrapper.Instance, snapshotValue);
6470
}
6571
}
6672

67-
[Obsolete("This method is obsolete and will be removed in a future release.")]
68-
public static PackageSpec GetPackageSpec(JObject rawPackageSpec, string name, string packageSpecPath, string snapshotValue)
73+
[Obsolete]
74+
internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string packageSpecPath)
6975
{
70-
using (var stringReader = new StringReader(rawPackageSpec.ToString()))
71-
using (var jsonReader = new JsonTextReader(stringReader))
76+
return GetPackageSpec(jsonReader, name: null, packageSpecPath, EnvironmentVariableWrapper.Instance);
77+
}
78+
79+
internal static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue, IEnvironmentVariableReader environmentVariableReader, bool bypassCache = false)
80+
{
81+
if (!JsonUtility.UseNewtonsoftJsonForParsing(environmentVariableReader, bypassCache))
7282
{
73-
return GetPackageSpec(jsonReader, name, packageSpecPath, EnvironmentVariableWrapper.Instance, snapshotValue);
83+
return GetPackageSpecUtf8JsonStreamReader(stream, name, packageSpecPath, environmentVariableReader, snapshotValue);
84+
}
85+
else
86+
{
87+
using (var textReader = new StreamReader(stream))
88+
using (var jsonReader = new JsonTextReader(textReader))
89+
{
90+
#pragma warning disable CS0612 // Type or member is obsolete
91+
return GetPackageSpec(jsonReader, name, packageSpecPath, environmentVariableReader, snapshotValue);
92+
#pragma warning restore CS0612 // Type or member is obsolete
93+
}
7494
}
7595
}
7696

97+
[Obsolete]
7798
internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string name, string packageSpecPath, IEnvironmentVariableReader environmentVariableReader, string snapshotValue = null)
7899
{
79100
var packageSpec = new PackageSpec();
@@ -232,6 +253,7 @@ internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string nam
232253
return packageSpec;
233254
}
234255

256+
[Obsolete]
235257
private static PackageType CreatePackageType(JsonTextReader jsonReader)
236258
{
237259
var name = (string)jsonReader.Value;
@@ -253,6 +275,7 @@ private static void ReadBuildOptions(JsonTextReader jsonReader, PackageSpec pack
253275
});
254276
}
255277

278+
[Obsolete]
256279
private static void ReadCentralPackageVersions(
257280
JsonTextReader jsonReader,
258281
IDictionary<string, CentralPackageVersion> centralPackageVersions,
@@ -287,6 +310,7 @@ private static void ReadCentralPackageVersions(
287310
});
288311
}
289312

313+
[Obsolete]
290314
private static CompatibilityProfile ReadCompatibilityProfile(JsonTextReader jsonReader, string profileName)
291315
{
292316
List<FrameworkRuntimePair> sets = null;
@@ -303,6 +327,7 @@ private static CompatibilityProfile ReadCompatibilityProfile(JsonTextReader json
303327
return new CompatibilityProfile(profileName, sets ?? Enumerable.Empty<FrameworkRuntimePair>());
304328
}
305329

330+
[Obsolete]
306331
private static IEnumerable<FrameworkRuntimePair> ReadCompatibilitySets(JsonTextReader jsonReader, string compatibilitySetName)
307332
{
308333
NuGetFramework framework = NuGetFramework.Parse(compatibilitySetName);
@@ -315,7 +340,8 @@ private static IEnumerable<FrameworkRuntimePair> ReadCompatibilitySets(JsonTextR
315340
}
316341
}
317342

318-
internal static void ReadDependencies(
343+
[Obsolete]
344+
private static void ReadDependencies(
319345
JsonTextReader jsonReader,
320346
IList<LibraryDependency> results,
321347
string packageSpecPath,
@@ -509,6 +535,7 @@ internal static void ReadDependencies(
509535
});
510536
}
511537

538+
[Obsolete]
512539
internal static void ReadCentralTransitiveDependencyGroup(
513540
JsonTextReader jsonReader,
514541
IList<LibraryDependency> results,
@@ -631,6 +658,7 @@ internal static void ReadCentralTransitiveDependencyGroup(
631658
});
632659
}
633660

661+
[Obsolete]
634662
private static void ReadDownloadDependencies(
635663
JsonTextReader jsonReader,
636664
IList<DownloadDependency> downloadDependencies,
@@ -721,13 +749,15 @@ private static void ReadDownloadDependencies(
721749
}
722750
}
723751

752+
[Obsolete]
724753
private static IReadOnlyList<string> ReadEnumerableOfString(JsonTextReader jsonReader)
725754
{
726755
string value = jsonReader.ReadNextTokenAsString();
727756

728757
return value.Split(DelimitedStringSeparators, StringSplitOptions.RemoveEmptyEntries);
729758
}
730759

760+
[Obsolete]
731761
private static void ReadFrameworkReferences(
732762
JsonTextReader jsonReader,
733763
ISet<FrameworkDependency> frameworkReferences,
@@ -763,6 +793,7 @@ private static void ReadFrameworkReferences(
763793
});
764794
}
765795

796+
[Obsolete]
766797
private static void ReadFrameworks(JsonTextReader jsonReader, PackageSpec packageSpec)
767798
{
768799
jsonReader.ReadObject(_ =>
@@ -781,6 +812,7 @@ private static void ReadFrameworks(JsonTextReader jsonReader, PackageSpec packag
781812
});
782813
}
783814

815+
[Obsolete]
784816
private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonReader, TargetFrameworkInformation targetFrameworkInformation)
785817
{
786818
int lineNumber = jsonReader.LineNumber;
@@ -812,6 +844,7 @@ private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonRead
812844
}
813845
}
814846

847+
[Obsolete]
815848
private static void ReadMappings(JsonTextReader jsonReader, string mappingKey, IDictionary<string, IncludeExcludeFiles> mappings)
816849
{
817850
if (jsonReader.ReadNextToken())
@@ -889,6 +922,7 @@ private static void ReadMappings(JsonTextReader jsonReader, string mappingKey, I
889922
}
890923
}
891924

925+
[Obsolete]
892926
private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec packageSpec, IEnvironmentVariableReader environmentVariableReader)
893927
{
894928
var centralPackageVersionsManagementEnabled = false;
@@ -1233,6 +1267,7 @@ private static bool ReadNextTokenAsBoolOrFalse(JsonTextReader jsonReader, string
12331267
return false;
12341268
}
12351269

1270+
[Obsolete]
12361271
private static void ReadNuGetLogCodes(JsonTextReader jsonReader, HashSet<NuGetLogCode> hashCodes)
12371272
{
12381273
if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray)
@@ -1267,6 +1302,7 @@ private static IList<NuGetLogCode> ReadNuGetLogCodesList(JsonTextReader jsonRead
12671302
return items ?? Array.Empty<NuGetLogCode>();
12681303
}
12691304

1305+
[Obsolete]
12701306
private static void ReadPackageTypes(PackageSpec packageSpec, JsonTextReader jsonReader)
12711307
{
12721308
var errorLine = 0;
@@ -1471,7 +1507,8 @@ private static bool ReadPackOptionsFiles(PackageSpec packageSpec, JsonTextReader
14711507
return wasMappingsRead;
14721508
}
14731509

1474-
private static RuntimeDependencySet ReadRuntimeDependencySet(JsonTextReader jsonReader, string dependencySetName)
1510+
[Obsolete]
1511+
static RuntimeDependencySet ReadRuntimeDependencySet(JsonTextReader jsonReader, string dependencySetName)
14751512
{
14761513
List<RuntimePackageDependency> dependencies = null;
14771514

@@ -1489,6 +1526,7 @@ private static RuntimeDependencySet ReadRuntimeDependencySet(JsonTextReader json
14891526
dependencies);
14901527
}
14911528

1529+
[Obsolete]
14921530
private static RuntimeDescription ReadRuntimeDescription(JsonTextReader jsonReader, string runtimeName)
14931531
{
14941532
List<string> inheritedRuntimes = null;
@@ -1516,6 +1554,7 @@ private static RuntimeDescription ReadRuntimeDescription(JsonTextReader jsonRead
15161554
additionalDependencies);
15171555
}
15181556

1557+
[Obsolete]
15191558
private static List<RuntimeDescription> ReadRuntimes(JsonTextReader jsonReader)
15201559
{
15211560
var runtimeDescriptions = new List<RuntimeDescription>();
@@ -1564,13 +1603,15 @@ private static void ReadScripts(JsonTextReader jsonReader, PackageSpec packageSp
15641603
});
15651604
}
15661605

1606+
[Obsolete]
15671607
private static string[] ReadStringArray(JsonTextReader jsonReader)
15681608
{
15691609
List<string> list = jsonReader.ReadStringArrayAsList();
15701610

15711611
return list?.ToArray();
15721612
}
15731613

1614+
[Obsolete]
15741615
private static List<CompatibilityProfile> ReadSupports(JsonTextReader jsonReader)
15751616
{
15761617
var compatibilityProfiles = new List<CompatibilityProfile>();
@@ -1585,6 +1626,7 @@ private static List<CompatibilityProfile> ReadSupports(JsonTextReader jsonReader
15851626
return compatibilityProfiles;
15861627
}
15871628

1629+
[Obsolete]
15881630
private static LibraryDependencyTarget ReadTarget(
15891631
JsonTextReader jsonReader,
15901632
string packageSpecPath,
@@ -1615,6 +1657,7 @@ private static LibraryDependencyTarget ReadTarget(
16151657
return targetFlagsValue;
16161658
}
16171659

1660+
[Obsolete]
16181661
private static List<ProjectRestoreMetadataFrameworkInfo> ReadTargetFrameworks(JsonTextReader jsonReader)
16191662
{
16201663
var targetFrameworks = new List<ProjectRestoreMetadataFrameworkInfo>();
@@ -1688,6 +1731,7 @@ private static List<ProjectRestoreMetadataFrameworkInfo> ReadTargetFrameworks(Js
16881731
return targetFrameworks;
16891732
}
16901733

1734+
[Obsolete]
16911735
private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader jsonReader, out int frameworkLine, out int frameworkColumn)
16921736
{
16931737
frameworkLine = 0;
@@ -1768,6 +1812,12 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader
17681812
}
17691813
}, out frameworkLine, out frameworkColumn);
17701814

1815+
AddTargetFramework(packageSpec, frameworkName, secondaryFramework, targetFrameworkInformation);
1816+
}
1817+
1818+
[Obsolete]
1819+
private static void AddTargetFramework(PackageSpec packageSpec, NuGetFramework frameworkName, NuGetFramework secondaryFramework, TargetFrameworkInformation targetFrameworkInformation)
1820+
{
17711821
NuGetFramework updatedFramework = frameworkName;
17721822

17731823
if (targetFrameworkInformation.Imports.Count > 0)
@@ -1793,6 +1843,8 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader
17931843
packageSpec.TargetFrameworks.Add(targetFrameworkInformation);
17941844
}
17951845

1846+
1847+
[Obsolete]
17961848
private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework)
17971849
{
17981850
if (secondaryFramework != default)
@@ -1803,6 +1855,7 @@ private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramewo
18031855
return frameworkName;
18041856
}
18051857

1858+
[Obsolete]
18061859
private static bool ValidateDependencyTarget(LibraryDependencyTarget targetValue)
18071860
{
18081861
var isValid = false;

0 commit comments

Comments
 (0)