forked from Azure/bicep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LanguageServer.cs
116 lines (98 loc) · 3.89 KB
/
LanguageServer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Bicep.Core.Samples;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using System.IO.Abstractions;
using Bicep.Core.UnitTests.Utils;
using System.Threading.Tasks;
using OmniSharp.Extensions.LanguageServer.Client;
using System.IO.Pipelines;
using Bicep.LanguageServer;
using System.Threading;
using OmniSharp.Extensions.LanguageServer.Protocol.Client;
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
using OmniSharp.Extensions.LanguageServer.Protocol;
using System.Collections.Generic;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using Bicep.LangServer.IntegrationTests;
using System.Reactive.Concurrency;
namespace Bicep.Tools.Benchmark;
[MemoryDiagnoser]
public class LanguageServer
{
private record BenchmarkData(
ILanguageClient Client,
MultipleMessageListener<PublishDiagnosticsParams> DiagsListener);
private static async Task<BenchmarkData> CreateBenchmarkData()
{
var fileSystem = FileHelper.CreateMockFileSystemForEmbeddedFiles(typeof(DataSet).Assembly, "Files");
var diagsListener = new MultipleMessageListener<PublishDiagnosticsParams>();
var client = await StartServer(fileSystem, diagsListener);
return new(client, diagsListener);
}
private static async Task<ILanguageClient> StartServer(IFileSystem fileSystem, MultipleMessageListener<PublishDiagnosticsParams> diagsListener)
{
var clientPipe = new Pipe();
var serverPipe = new Pipe();
var server = new Server(options => options
.WithInput(serverPipe.Reader)
.WithOutput(clientPipe.Writer)
.WithServices(services => services
.AddSingleton<IScheduler>(ImmediateScheduler.Instance) // force work to run on a single thread to make snapshot profiling simpler
.AddSingleton(fileSystem)));
var _ = server.RunAsync(CancellationToken.None); // do not wait on this async method, or you'll be waiting a long time!
var client = LanguageClient.PreInit(options => {
options
.WithInput(clientPipe.Reader)
.WithOutput(serverPipe.Writer)
.OnPublishDiagnostics(x => diagsListener.AddMessage(x));
options.RegisterForDisposal(server);
});
await client.Initialize(CancellationToken.None);
return client;
}
private BenchmarkData? benchmarkData;
[GlobalSetup]
public async Task GlobalSetup()
{
this.benchmarkData = await CreateBenchmarkData();
}
[Benchmark(Description = "Type a document from start to finish")]
public async Task Type_a_document_from_start_to_finish()
{
var (client, diagsListener) = benchmarkData!;
var dataSet = DataSets.AKS_LF;
var version = 0;
var documentUri = DocumentUri.Parse($"file:https:///{dataSet.Name}/main.bicep");
client.DidOpenTextDocument(new() {
TextDocument = new () {
LanguageId = "bicep",
Text = "",
Uri = documentUri,
Version = version++,
},
});
var diags = await diagsListener.WaitNext();
for (var i = 0; i < dataSet.Bicep.Length; i++)
{
client.DidChangeTextDocument(new() {
TextDocument = new () {
Uri = documentUri,
Version = version++,
},
ContentChanges = new(new List<TextDocumentContentChangeEvent> {
new() {
Text = dataSet.Bicep.Substring(0, i),
},
}),
});
diags = await diagsListener.WaitNext();
}
client.DidCloseTextDocument(new() {
TextDocument = new () {
Uri = documentUri,
},
});
}
}