diff --git a/src/ServiceHost/LanguageService/Contracts/Completion.cs b/src/ServiceHost/LanguageService/Contracts/Completion.cs index 5f26ea96..ef78330d 100644 --- a/src/ServiceHost/LanguageService/Contracts/Completion.cs +++ b/src/ServiceHost/LanguageService/Contracts/Completion.cs @@ -4,9 +4,10 @@ // using System.Diagnostics; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class CompletionRequest { diff --git a/src/ServiceHost/LanguageService/Contracts/Definition.cs b/src/ServiceHost/LanguageService/Contracts/Definition.cs index b18845c3..b6a211e6 100644 --- a/src/ServiceHost/LanguageService/Contracts/Definition.cs +++ b/src/ServiceHost/LanguageService/Contracts/Definition.cs @@ -3,9 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class DefinitionRequest { diff --git a/src/ServiceHost/LanguageService/Contracts/Diagnostics.cs b/src/ServiceHost/LanguageService/Contracts/Diagnostics.cs index a5472607..c1895bdf 100644 --- a/src/ServiceHost/LanguageService/Contracts/Diagnostics.cs +++ b/src/ServiceHost/LanguageService/Contracts/Diagnostics.cs @@ -3,9 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class PublishDiagnosticsNotification { diff --git a/src/ServiceHost/LanguageService/Contracts/DocumentHighlight.cs b/src/ServiceHost/LanguageService/Contracts/DocumentHighlight.cs index 6849ddfb..db459eb4 100644 --- a/src/ServiceHost/LanguageService/Contracts/DocumentHighlight.cs +++ b/src/ServiceHost/LanguageService/Contracts/DocumentHighlight.cs @@ -3,9 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public enum DocumentHighlightKind { diff --git a/src/ServiceHost/LanguageService/Contracts/ExpandAliasRequest.cs b/src/ServiceHost/LanguageService/Contracts/ExpandAliasRequest.cs index d7f9fde4..7a970db5 100644 --- a/src/ServiceHost/LanguageService/Contracts/ExpandAliasRequest.cs +++ b/src/ServiceHost/LanguageService/Contracts/ExpandAliasRequest.cs @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class ExpandAliasRequest { diff --git a/src/ServiceHost/LanguageService/Contracts/FindModuleRequest.cs b/src/ServiceHost/LanguageService/Contracts/FindModuleRequest.cs index ab78a158..dff3939c 100644 --- a/src/ServiceHost/LanguageService/Contracts/FindModuleRequest.cs +++ b/src/ServiceHost/LanguageService/Contracts/FindModuleRequest.cs @@ -3,10 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; using System.Collections.Generic; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class FindModuleRequest { diff --git a/src/ServiceHost/LanguageService/Contracts/Hover.cs b/src/ServiceHost/LanguageService/Contracts/Hover.cs index 2e196fba..dd7f05c0 100644 --- a/src/ServiceHost/LanguageService/Contracts/Hover.cs +++ b/src/ServiceHost/LanguageService/Contracts/Hover.cs @@ -3,9 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class MarkedString { diff --git a/src/ServiceHost/LanguageService/Contracts/InstallModuleRequest.cs b/src/ServiceHost/LanguageService/Contracts/InstallModuleRequest.cs index b03b8864..361bb60f 100644 --- a/src/ServiceHost/LanguageService/Contracts/InstallModuleRequest.cs +++ b/src/ServiceHost/LanguageService/Contracts/InstallModuleRequest.cs @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { class InstallModuleRequest { diff --git a/src/ServiceHost/LanguageService/Contracts/References.cs b/src/ServiceHost/LanguageService/Contracts/References.cs index 25a92b12..d2e12ccd 100644 --- a/src/ServiceHost/LanguageService/Contracts/References.cs +++ b/src/ServiceHost/LanguageService/Contracts/References.cs @@ -3,9 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class ReferencesRequest { diff --git a/src/ServiceHost/LanguageService/Contracts/ShowOnlineHelpRequest.cs b/src/ServiceHost/LanguageService/Contracts/ShowOnlineHelpRequest.cs index 8f21fb1b..d77eeafa 100644 --- a/src/ServiceHost/LanguageService/Contracts/ShowOnlineHelpRequest.cs +++ b/src/ServiceHost/LanguageService/Contracts/ShowOnlineHelpRequest.cs @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class ShowOnlineHelpRequest { diff --git a/src/ServiceHost/LanguageService/Contracts/SignatureHelp.cs b/src/ServiceHost/LanguageService/Contracts/SignatureHelp.cs index 5d4233e3..26e62b21 100644 --- a/src/ServiceHost/LanguageService/Contracts/SignatureHelp.cs +++ b/src/ServiceHost/LanguageService/Contracts/SignatureHelp.cs @@ -3,9 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts { public class SignatureHelpRequest { diff --git a/src/ServiceHost/LanguageService/LanguageService.cs b/src/ServiceHost/LanguageService/LanguageService.cs index 3ab77697..51665fbd 100644 --- a/src/ServiceHost/LanguageService/LanguageService.cs +++ b/src/ServiceHost/LanguageService/LanguageService.cs @@ -3,31 +3,160 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices; +using System.Threading.Tasks; using Microsoft.SqlTools.EditorServices.Session; +using Microsoft.SqlTools.EditorServices.Utility; +using Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; -namespace Microsoft.SqlTools.LanguageSupport +namespace Microsoft.SqlTools.ServiceLayer.LanguageService { /// /// Main class for Language Service functionality /// public class LanguageService { + + #region Singleton Instance Implementation + + private static LanguageService instance; + + public static LanguageService Instance + { + get + { + if (instance == null) + { + instance = new LanguageService(); + } + return instance; + } + } + + /// + /// Constructor for the Language Service class + /// + /// + private LanguageService(SqlToolsContext context) + { + this.Context = context; + } + + /// + /// Default, parameterless contstructor. + /// TODO: Remove once the SqlToolsContext stuff is sorted out + /// + private LanguageService() + { + + } + + #endregion + /// /// Gets or sets the current SQL Tools context /// /// private SqlToolsContext Context { get; set; } - /// - /// Constructor for the Language Service class - /// - /// - public LanguageService(SqlToolsContext context) + public void InitializeService(ServiceHost.ServiceHost serviceHost) { - this.Context = context; + // Register the requests that this service will handle + serviceHost.SetRequestHandler(DefinitionRequest.Type, HandleDefinitionRequest); + serviceHost.SetRequestHandler(ReferencesRequest.Type, HandleReferencesRequest); + serviceHost.SetRequestHandler(CompletionRequest.Type, HandleCompletionRequest); + serviceHost.SetRequestHandler(CompletionResolveRequest.Type, HandleCompletionResolveRequest); + serviceHost.SetRequestHandler(SignatureHelpRequest.Type, HandleSignatureHelpRequest); + serviceHost.SetRequestHandler(DocumentHighlightRequest.Type, HandleDocumentHighlightRequest); + serviceHost.SetRequestHandler(HoverRequest.Type, HandleHoverRequest); + serviceHost.SetRequestHandler(DocumentSymbolRequest.Type, HandleDocumentSymbolRequest); + serviceHost.SetRequestHandler(WorkspaceSymbolRequest.Type, HandleWorkspaceSymbolRequest); + + // Register a no-op shutdown task for validation of the shutdown logic + serviceHost.RegisterShutdownTask(async (shutdownParams, shutdownRequestContext) => + { + Logger.Write(LogLevel.Verbose, "Shutting down language service"); + await Task.FromResult(0); + }); } + #region Request Handlers + + private static async Task HandleDefinitionRequest( + TextDocumentPosition textDocumentPosition, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleDefinitionRequest"); + await Task.FromResult(true); + } + + private static async Task HandleReferencesRequest( + ReferencesParams referencesParams, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleReferencesRequest"); + await Task.FromResult(true); + } + + private static async Task HandleCompletionRequest( + TextDocumentPosition textDocumentPosition, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleCompletionRequest"); + await Task.FromResult(true); + } + + private static async Task HandleCompletionResolveRequest( + CompletionItem completionItem, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleCompletionResolveRequest"); + await Task.FromResult(true); + } + + private static async Task HandleSignatureHelpRequest( + TextDocumentPosition textDocumentPosition, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleSignatureHelpRequest"); + await Task.FromResult(true); + } + + private static async Task HandleDocumentHighlightRequest( + TextDocumentPosition textDocumentPosition, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleDocumentHighlightRequest"); + await Task.FromResult(true); + } + + private static async Task HandleHoverRequest( + TextDocumentPosition textDocumentPosition, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleHoverRequest"); + await Task.FromResult(true); + } + + private static async Task HandleDocumentSymbolRequest( + TextDocumentIdentifier textDocumentIdentifier, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleDocumentSymbolRequest"); + await Task.FromResult(true); + } + + private static async Task HandleWorkspaceSymbolRequest( + WorkspaceSymbolParams workspaceSymbolParams, + RequestContext requestContext) + { + Logger.Write(LogLevel.Verbose, "HandleWorkspaceSymbolRequest"); + await Task.FromResult(true); + } + + #endregion + /// /// Gets a list of semantic diagnostic marks for the provided script file /// diff --git a/src/ServiceHost/Program.cs b/src/ServiceHost/Program.cs index 6bfd0f24..fda85c74 100644 --- a/src/ServiceHost/Program.cs +++ b/src/ServiceHost/Program.cs @@ -2,11 +2,10 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using Microsoft.SqlTools.EditorServices.Protocol.Server; using Microsoft.SqlTools.EditorServices.Session; using Microsoft.SqlTools.EditorServices.Utility; -namespace Microsoft.SqlTools.ServiceHost +namespace Microsoft.SqlTools.ServiceLayer { /// /// Main application class for SQL Tools API Service Host executable @@ -31,10 +30,15 @@ namespace Microsoft.SqlTools.ServiceHost var hostDetails = new HostDetails(hostName, hostProfileId, hostVersion); var profilePaths = new ProfilePaths(hostProfileId, "baseAllUsersPath", "baseCurrentUserPath"); - // create and run the language server - var languageServer = new LanguageServer(hostDetails, profilePaths); - languageServer.Start().Wait(); - languageServer.WaitForExit(); + // Create the service host + ServiceHost.ServiceHost serviceHost = ServiceHost.ServiceHost.Create(hostDetails, profilePaths); + + // Initialize the services that will be hosted here + LanguageService.LanguageService.Instance.InitializeService(serviceHost); + + // Start the service + serviceHost.Start().Wait(); + serviceHost.WaitForExit(); } } } diff --git a/src/ServiceHost/ServerService/Contracts/ClientCapabilities.cs b/src/ServiceHost/ServiceHost/Contracts/ClientCapabilities.cs similarity index 85% rename from src/ServiceHost/ServerService/Contracts/ClientCapabilities.cs rename to src/ServiceHost/ServiceHost/Contracts/ClientCapabilities.cs index 70e2d068..e8b084e7 100644 --- a/src/ServiceHost/ServerService/Contracts/ClientCapabilities.cs +++ b/src/ServiceHost/ServiceHost/Contracts/ClientCapabilities.cs @@ -4,7 +4,7 @@ // -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Contracts { /// /// Defines a class that describes the capabilities of a language diff --git a/src/ServiceHost/ServerService/Contracts/Initialize.cs b/src/ServiceHost/ServiceHost/Contracts/Initialize.cs similarity index 91% rename from src/ServiceHost/ServerService/Contracts/Initialize.cs rename to src/ServiceHost/ServiceHost/Contracts/Initialize.cs index 7551835e..a5dc1eff 100644 --- a/src/ServiceHost/ServerService/Contracts/Initialize.cs +++ b/src/ServiceHost/ServiceHost/Contracts/Initialize.cs @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Contracts { public class InitializeRequest { diff --git a/src/ServiceHost/ServerService/Contracts/ServerCapabilities.cs b/src/ServiceHost/ServiceHost/Contracts/ServerCapabilities.cs similarity index 96% rename from src/ServiceHost/ServerService/Contracts/ServerCapabilities.cs rename to src/ServiceHost/ServiceHost/Contracts/ServerCapabilities.cs index 2f7404d9..f378aa9e 100644 --- a/src/ServiceHost/ServerService/Contracts/ServerCapabilities.cs +++ b/src/ServiceHost/ServiceHost/Contracts/ServerCapabilities.cs @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Contracts { public class ServerCapabilities { diff --git a/src/ServiceHost/ServerService/Contracts/Shutdown.cs b/src/ServiceHost/ServiceHost/Contracts/Shutdown.cs similarity index 85% rename from src/ServiceHost/ServerService/Contracts/Shutdown.cs rename to src/ServiceHost/ServiceHost/Contracts/Shutdown.cs index f0a7bbd2..395aaef0 100644 --- a/src/ServiceHost/ServerService/Contracts/Shutdown.cs +++ b/src/ServiceHost/ServiceHost/Contracts/Shutdown.cs @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Contracts { /// /// Defines a message that is sent from the client to request diff --git a/src/ServiceHost/ServiceHost/Protocol/Channel/ChannelBase.cs b/src/ServiceHost/ServiceHost/Protocol/Channel/ChannelBase.cs index 622e5826..3d55ace4 100644 --- a/src/ServiceHost/ServiceHost/Protocol/Channel/ChannelBase.cs +++ b/src/ServiceHost/ServiceHost/Protocol/Channel/ChannelBase.cs @@ -3,8 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol.Serializers; using System.Threading.Tasks; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Serializers; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Channel { diff --git a/src/ServiceHost/ServiceHost/Protocol/Channel/StdioClientChannel.cs b/src/ServiceHost/ServiceHost/Protocol/Channel/StdioClientChannel.cs index e8645d38..83bf5c38 100644 --- a/src/ServiceHost/ServiceHost/Protocol/Channel/StdioClientChannel.cs +++ b/src/ServiceHost/ServiceHost/Protocol/Channel/StdioClientChannel.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.IO; using System.Text; using System.Threading.Tasks; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Serializers; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Channel { diff --git a/src/ServiceHost/ServiceHost/Protocol/Channel/StdioServerChannel.cs b/src/ServiceHost/ServiceHost/Protocol/Channel/StdioServerChannel.cs index 46fd5d0f..9aa164e2 100644 --- a/src/ServiceHost/ServiceHost/Protocol/Channel/StdioServerChannel.cs +++ b/src/ServiceHost/ServiceHost/Protocol/Channel/StdioServerChannel.cs @@ -6,6 +6,7 @@ using System.IO; using System.Text; using System.Threading.Tasks; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Serializers; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Channel { diff --git a/src/ServiceHost/ServiceHost/Protocol/MessageDispatcher.cs b/src/ServiceHost/ServiceHost/Protocol/MessageDispatcher.cs index 58f541d2..fe4ccdff 100644 --- a/src/ServiceHost/ServiceHost/Protocol/MessageDispatcher.cs +++ b/src/ServiceHost/ServiceHost/Protocol/MessageDispatcher.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Channel; using Microsoft.SqlTools.EditorServices.Utility; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol { diff --git a/src/ServiceHost/ServiceHost/Protocol/Serializers/IMessageSerializer.cs b/src/ServiceHost/ServiceHost/Protocol/Serializers/IMessageSerializer.cs index 318955fd..de537b1d 100644 --- a/src/ServiceHost/ServiceHost/Protocol/Serializers/IMessageSerializer.cs +++ b/src/ServiceHost/ServiceHost/Protocol/Serializers/IMessageSerializer.cs @@ -3,6 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; using Newtonsoft.Json.Linq; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Serializers diff --git a/src/ServiceHost/ServiceHost/Protocol/Serializers/JsonRpcMessageSerializer.cs b/src/ServiceHost/ServiceHost/Protocol/Serializers/JsonRpcMessageSerializer.cs index 194f270d..bf29a530 100644 --- a/src/ServiceHost/ServiceHost/Protocol/Serializers/JsonRpcMessageSerializer.cs +++ b/src/ServiceHost/ServiceHost/Protocol/Serializers/JsonRpcMessageSerializer.cs @@ -3,6 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; using Newtonsoft.Json.Linq; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Serializers diff --git a/src/ServiceHost/ServiceHost/Protocol/Serializers/V8MessageSerializer.cs b/src/ServiceHost/ServiceHost/Protocol/Serializers/V8MessageSerializer.cs index 81af48f5..7ac68143 100644 --- a/src/ServiceHost/ServiceHost/Protocol/Serializers/V8MessageSerializer.cs +++ b/src/ServiceHost/ServiceHost/Protocol/Serializers/V8MessageSerializer.cs @@ -5,6 +5,7 @@ using Newtonsoft.Json.Linq; using System; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Serializers { diff --git a/src/ServiceHost/ServiceHost/ServiceHost.cs b/src/ServiceHost/ServiceHost/ServiceHost.cs index 53337392..0b393e3f 100644 --- a/src/ServiceHost/ServiceHost/ServiceHost.cs +++ b/src/ServiceHost/ServiceHost/ServiceHost.cs @@ -10,11 +10,13 @@ using System.Threading; using System.Linq; using System; using Microsoft.SqlTools.EditorServices; -using Microsoft.SqlTools.EditorServices.Protocol.LanguageServer; using Microsoft.SqlTools.EditorServices.Session; using Microsoft.SqlTools.EditorServices.Utility; +using Microsoft.SqlTools.ServiceLayer.LanguageService.Contracts; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Contracts; using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol; using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Channel; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; namespace Microsoft.SqlTools.ServiceLayer.ServiceHost { @@ -23,59 +25,115 @@ namespace Microsoft.SqlTools.ServiceLayer.ServiceHost /// public class ServiceHost : ServiceHostBase { + #region Singleton Instance Code + + /// + /// Singleton instance of the instance + /// + private static ServiceHost instance; + + /// + /// Creates or retrieves the current instance of the ServiceHost + /// + /// Details about the host application + /// Details about the profile + /// Instance of the service host + public static ServiceHost Create(HostDetails hostDetails, ProfilePaths profilePaths) + { + if (instance == null) + { + instance = new ServiceHost(hostDetails, profilePaths); + } + // TODO: hostDetails and profilePaths are thrown out in SqlDataToolsContext, + // so we don't need to keep track of whether these have changed for now. + + return instance; + } + + /// + /// Constructs new instance of ServiceHost using the host and profile details provided. + /// Access is private to ensure only one instance exists at a time. + /// + /// Details about the host application + /// Details about the profile + private ServiceHost(HostDetails hostDetails, ProfilePaths profilePaths) + : base(new StdioServerChannel()) + { + // Initialize the shutdown activities + shutdownActivities = new List(); + + // Create an editor session that we'll use for keeping track of state + this.editorSession = new EditorSession(); + this.editorSession.StartSession(hostDetails, profilePaths); + + // Register the requests that this service host will handle + this.SetRequestHandler(InitializeRequest.Type, this.HandleInitializeRequest); + this.SetRequestHandler(ShutdownRequest.Type, this.HandleShutdownRequest); + } + + #endregion + + #region Member Variables + private static CancellationTokenSource existingRequestCancellation; private ServiceHostSettings currentSettings = new ServiceHostSettings(); private EditorSession editorSession; - /// - /// Provides details about the host application. - /// - public ServiceHost(HostDetails hostDetails, ProfilePaths profilePaths) - : base(new StdioServerChannel()) + public delegate Task ShutdownHandler(object shutdownParams, RequestContext shutdownRequestContext); + + private readonly List shutdownActivities; + + #endregion + + #region Public Methods + + /// + /// Adds a new method to be called when the shutdown request is submitted + /// + /// + public void RegisterShutdownTask(ShutdownHandler activity) { - this.editorSession = new EditorSession(); - this.editorSession.StartSession(hostDetails, profilePaths); + shutdownActivities.Add(activity); } + #endregion + + #region Private Methods + /// /// Initialize the VS Code request/response callbacks /// - protected override void Initialize() + private void Initialize() { // Register all supported message types - this.SetRequestHandler(InitializeRequest.Type, this.HandleInitializeRequest); + this.SetEventHandler(DidChangeTextDocumentNotification.Type, this.HandleDidChangeTextDocumentNotification); this.SetEventHandler(DidOpenTextDocumentNotification.Type, this.HandleDidOpenTextDocumentNotification); this.SetEventHandler(DidCloseTextDocumentNotification.Type, this.HandleDidCloseTextDocumentNotification); this.SetEventHandler(DidChangeConfigurationNotification.Type, this.HandleDidChangeConfigurationNotification); - this.SetRequestHandler(DefinitionRequest.Type, this.HandleDefinitionRequest); - this.SetRequestHandler(ReferencesRequest.Type, this.HandleReferencesRequest); - this.SetRequestHandler(CompletionRequest.Type, this.HandleCompletionRequest); - this.SetRequestHandler(CompletionResolveRequest.Type, this.HandleCompletionResolveRequest); - this.SetRequestHandler(SignatureHelpRequest.Type, this.HandleSignatureHelpRequest); - this.SetRequestHandler(DocumentHighlightRequest.Type, this.HandleDocumentHighlightRequest); - this.SetRequestHandler(HoverRequest.Type, this.HandleHoverRequest); - this.SetRequestHandler(DocumentSymbolRequest.Type, this.HandleDocumentSymbolRequest); - this.SetRequestHandler(WorkspaceSymbolRequest.Type, this.HandleWorkspaceSymbolRequest); + } /// /// Handles the shutdown event for the Language Server /// - protected override async Task Shutdown() + private async Task HandleShutdownRequest(object shutdownParams, RequestContext requestContext) { - Logger.Write(LogLevel.Normal, "Language service is shutting down..."); + Logger.Write(LogLevel.Normal, "Service host is shutting down..."); + // Call all the shutdown methods provided by the service components + Task[] shutdownTasks = shutdownActivities.Select(t => t(shutdownParams, requestContext)).ToArray(); + await Task.WhenAll(shutdownTasks); + + // Shutdown the editor session if (this.editorSession != null) { this.editorSession.Dispose(); this.editorSession = null; } - - await Task.FromResult(true); } /// @@ -84,11 +142,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ServiceHost /// /// /// - protected async Task HandleInitializeRequest( - InitializeRequest initializeParams, - RequestContext requestContext) + private async Task HandleInitializeRequest(InitializeRequest initializeParams, RequestContext requestContext) { - Logger.Write(LogLevel.Verbose, "HandleDidChangeTextDocumentNotification"); + Logger.Write(LogLevel.Verbose, "HandleInitializationRequest"); // Grab the workspace path from the parameters editorSession.Workspace.WorkspacePath = initializeParams.RootPath; @@ -118,6 +174,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ServiceHost }); } + #endregion + + /////////////////////////////////////////////// + + /// /// Handles text document change events /// @@ -226,78 +287,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ServiceHost await Task.FromResult(true); } - protected async Task HandleDefinitionRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleDefinitionRequest"); - await Task.FromResult(true); - } - - protected async Task HandleReferencesRequest( - ReferencesParams referencesParams, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleReferencesRequest"); - await Task.FromResult(true); - } - - protected async Task HandleCompletionRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleCompletionRequest"); - await Task.FromResult(true); - } - - protected async Task HandleCompletionResolveRequest( - CompletionItem completionItem, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleCompletionResolveRequest"); - await Task.FromResult(true); - } - - protected async Task HandleSignatureHelpRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleSignatureHelpRequest"); - await Task.FromResult(true); - } - - protected async Task HandleDocumentHighlightRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleDocumentHighlightRequest"); - await Task.FromResult(true); - } - - protected async Task HandleHoverRequest( - TextDocumentPosition textDocumentPosition, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleHoverRequest"); - await Task.FromResult(true); - } - - protected async Task HandleDocumentSymbolRequest( - TextDocumentIdentifier textDocumentIdentifier, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleDocumentSymbolRequest"); - await Task.FromResult(true); - } - - protected async Task HandleWorkspaceSymbolRequest( - WorkspaceSymbolParams workspaceSymbolParams, - RequestContext requestContext) - { - Logger.Write(LogLevel.Verbose, "HandleWorkspaceSymbolRequest"); - await Task.FromResult(true); - } - /// /// Runs script diagnostics on changed files /// @@ -333,7 +322,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ServiceHost { Logger.Write( LogLevel.Error, - string.Format( + String.Format( "Exception while cancelling analysis task:\n\n{0}", e.ToString())); diff --git a/src/ServiceHost/ServiceHost/ServiceHostBase.cs b/src/ServiceHost/ServiceHost/ServiceHostBase.cs index b89c90eb..eb6ec946 100644 --- a/src/ServiceHost/ServiceHost/ServiceHostBase.cs +++ b/src/ServiceHost/ServiceHost/ServiceHostBase.cs @@ -4,7 +4,7 @@ // using System.Threading.Tasks; -using Microsoft.SqlTools.EditorServices.Protocol.LanguageServer; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Contracts; using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol; using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Channel; @@ -13,59 +13,22 @@ namespace Microsoft.SqlTools.ServiceLayer.ServiceHost public abstract class ServiceHostBase : ProtocolEndpoint { private bool isStarted; - private ChannelBase serverChannel; private TaskCompletionSource serverExitedTask; public ServiceHostBase(ChannelBase serverChannel) : base(serverChannel, MessageProtocolType.LanguageServer) { - this.serverChannel = serverChannel; } protected override Task OnStart() { // Register handlers for server lifetime messages - this.SetRequestHandler(ShutdownRequest.Type, this.HandleShutdownRequest); + this.SetEventHandler(ExitNotification.Type, this.HandleExitNotification); - // Initialize the implementation class - this.Initialize(); - return Task.FromResult(true); } - protected override async Task OnStop() - { - await this.Shutdown(); - } - - /// - /// Overridden by the subclass to provide initialization - /// logic after the server channel is started. - /// - protected abstract void Initialize(); - - /// - /// Can be overridden by the subclass to provide shutdown - /// logic before the server exits. Subclasses do not need - /// to invoke or return the value of the base implementation. - /// - protected virtual Task Shutdown() - { - // No default implementation yet. - return Task.FromResult(true); - } - - private async Task HandleShutdownRequest( - object shutdownParams, - RequestContext requestContext) - { - // Allow the implementor to shut down gracefully - await this.Shutdown(); - - await requestContext.SendResult(new object()); - } - private async Task HandleExitNotification( object exitParams, EventContext eventContext) diff --git a/src/ServiceHost/Session/EditorSession.cs b/src/ServiceHost/Session/EditorSession.cs index 3c592a8f..7b3dcc46 100644 --- a/src/ServiceHost/Session/EditorSession.cs +++ b/src/ServiceHost/Session/EditorSession.cs @@ -5,7 +5,8 @@ using System; using Microsoft.SqlTools.EditorServices.Session; -using Microsoft.SqlTools.LanguageSupport; +using Microsoft.SqlTools.ServiceLayer.LanguageService; +using Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts; namespace Microsoft.SqlTools.EditorServices { diff --git a/src/ServiceHost/WorkspaceService/Contracts/BufferPosition.cs b/src/ServiceHost/WorkspaceService/Contracts/BufferPosition.cs index 8f790d85..020548f6 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/BufferPosition.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/BufferPosition.cs @@ -5,7 +5,7 @@ using System.Diagnostics; -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Provides details about a position in a file buffer. All diff --git a/src/ServiceHost/WorkspaceService/Contracts/BufferRange.cs b/src/ServiceHost/WorkspaceService/Contracts/BufferRange.cs index 5d20598f..f46abb96 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/BufferRange.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/BufferRange.cs @@ -6,7 +6,7 @@ using System; using System.Diagnostics; -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Provides details about a range between two positions in diff --git a/src/ServiceHost/WorkspaceService/Contracts/Configuration.cs b/src/ServiceHost/WorkspaceService/Contracts/Configuration.cs index b9ad87db..45697554 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/Configuration.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/Configuration.cs @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { public class DidChangeConfigurationNotification { diff --git a/src/ServiceHost/WorkspaceService/Contracts/FileChange.cs b/src/ServiceHost/WorkspaceService/Contracts/FileChange.cs index 2f6efdf8..a4398afe 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/FileChange.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/FileChange.cs @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Contains details relating to a content change in an open file. diff --git a/src/ServiceHost/WorkspaceService/Contracts/FilePosition.cs b/src/ServiceHost/WorkspaceService/Contracts/FilePosition.cs index 2cb58745..13e205ca 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/FilePosition.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/FilePosition.cs @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Provides details and operations for a buffer position in a diff --git a/src/ServiceHost/WorkspaceService/Contracts/ScriptFile.cs b/src/ServiceHost/WorkspaceService/Contracts/ScriptFile.cs index 90d66244..4e30b840 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/ScriptFile.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/ScriptFile.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Contains the details and contents of an open script file. diff --git a/src/ServiceHost/WorkspaceService/Contracts/ScriptFileMarker.cs b/src/ServiceHost/WorkspaceService/Contracts/ScriptFileMarker.cs index 87c2576c..a43de169 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/ScriptFileMarker.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/ScriptFileMarker.cs @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Defines the message level of a script file marker. diff --git a/src/ServiceHost/WorkspaceService/Contracts/ScriptRegion.cs b/src/ServiceHost/WorkspaceService/Contracts/ScriptRegion.cs index f2fa4ac8..943e2252 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/ScriptRegion.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/ScriptRegion.cs @@ -5,7 +5,7 @@ //using System.Management.Automation.Language; -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Contains details about a specific region of text in script file. diff --git a/src/ServiceHost/WorkspaceService/Contracts/TextDocument.cs b/src/ServiceHost/WorkspaceService/Contracts/TextDocument.cs index 9f477374..e091b315 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/TextDocument.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/TextDocument.cs @@ -4,9 +4,9 @@ // using System.Diagnostics; -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Defines a base parameter class for identifying a text document. diff --git a/src/ServiceHost/WorkspaceService/Contracts/Workspace.cs b/src/ServiceHost/WorkspaceService/Contracts/Workspace.cs index 39e1d70f..83b655fd 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/Workspace.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/Workspace.cs @@ -11,7 +11,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Linq; -namespace Microsoft.SqlTools.EditorServices +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { /// /// Manages a "workspace" of script files that are open for a particular diff --git a/src/ServiceHost/WorkspaceService/Contracts/WorkspaceSymbols.cs b/src/ServiceHost/WorkspaceService/Contracts/WorkspaceSymbols.cs index 25a554b5..347a9468 100644 --- a/src/ServiceHost/WorkspaceService/Contracts/WorkspaceSymbols.cs +++ b/src/ServiceHost/WorkspaceService/Contracts/WorkspaceSymbols.cs @@ -3,9 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlTools.EditorServices.Protocol.MessageProtocol; +using Microsoft.SqlTools.ServiceLayer.ServiceHost.Protocol.Contracts; -namespace Microsoft.SqlTools.EditorServices.Protocol.LanguageServer +namespace Microsoft.SqlTools.ServiceLayer.WorkspaceService.Contracts { public enum SymbolKind {