text: /* --------------------------------------------------------------------------------------------
   * Copyright (c) 2018 TypeFox GmbH (http://www.typefox.io). All rights reserved.
   * Licensed under the MIT License. See License.txt in the project root for license information.
   * ------------------------------------------------------------------------------------------ */
  import {
      BaseLanguageClient, MessageTransports, LanguageClientOptions,
      CompletionParams, WillSaveTextDocumentParams, StaticFeature, DynamicFeature
  } from "vscode-languageclient/lib/client";
  import { TypeDefinitionFeature } from "vscode-languageclient/lib/typeDefinition";
  import { ConfigurationFeature as PullConfigurationFeature } from "vscode-languageclient/lib/configuration";
  import { ImplementationFeature } from "vscode-languageclient/lib/implementation";
  import { ColorProviderFeature } from "vscode-languageclient/lib/colorProvider";
  import { WorkspaceFoldersFeature } from "vscode-languageclient/lib/workspaceFolders";
  import { FoldingRangeFeature } from "vscode-languageclient/lib/foldingRange";
  import { CallHierarchyFeature } from "vscode-languageclient/lib/callHierarchy.proposed";
  import { SemanticTokensFeature } from "vscode-languageclient/lib/semanticTokens.proposed";
  import * as p2c from 'vscode-languageclient/lib/protocolConverter';
  import * as c2p from 'vscode-languageclient/lib/codeConverter';
  import { IConnectionProvider, IConnection } from './connection';
  import { DeclarationFeature } from "vscode-languageclient/lib/declaration";
  
  export * from 'vscode-languageclient/lib/client';
  
  export class MonacoLanguageClient extends BaseLanguageClient {
  
      static bypassConversion = (result: any) => result || undefined;
  
      protected readonly connectionProvider: IConnectionProvider;
  
      constructor({ id, name, clientOptions, connectionProvider }: MonacoLanguageClient.Options) {
          super(id || name.toLowerCase(), name, clientOptions);
          this.connectionProvider = connectionProvider;
          (this as any).createConnection = this.doCreateConnection.bind(this);
  
          // bypass LSP <=> VS Code conversion
          const self: {
              _p2c: p2c.Converter,
              _c2p: c2p.Converter
          } = this as any;
          self._p2c = new Proxy(self._p2c, {
              get: (target: any, prop: string) => {
                  if (prop === 'asUri') {
                      return target[prop];
                  }
                  return MonacoLanguageClient.bypassConversion;
              }
          });
          self._c2p = new Proxy(self._c2p, {
              get: (target: c2p.Converter, prop: string) => {
                  if (prop === 'asUri') {
                      return target[prop];
                  }
                  if (prop === 'asCompletionParams') {
                      return (textDocument: any, position: any, context: any): CompletionParams => {
                          return {
                              textDocument: target.asTextDocumentIdentifier(textDocument),
                              position,
                              context
                          }
                      }
                  }
                  if (prop === 'asWillSaveTextDocumentParams') {
                      return (event: any): WillSaveTextDocumentParams => {
                          return {
                              textDocument: target.asTextDocumentIdentifier(event.document),
                              reason: event.reason
                          }
                      }
                  }
                  if (prop.endsWith('Params')) {
                      return (target as any)[prop];
                  }
                  return MonacoLanguageClient.bypassConversion;
              }
          });
      }
  
      protected doCreateConnection(): Thenable<IConnection> {
          const errorHandler = (this as any).handleConnectionError.bind(this);
          const closeHandler = this.handleConnectionClosed.bind(this);
          return this.connectionProvider.get(errorHandler, closeHandler, this.outputChannel);
      }
  
      protected createMessageTransports(encoding: string): Promise<MessageTransports> {
          throw new Error('Unsupported');
      }
  
      protected registerBuiltinFeatures(): void {
          super.registerBuiltinFeatures();
          this.registerFeature(new PullConfigurationFeature(this));
          this.registerFeature(new TypeDefinitionFeature(this));
          this.registerFeature(new ImplementationFeature(this));
          this.registerFeature(new ColorProviderFeature(this));
          this.registerFeature(new WorkspaceFoldersFeature(this));
          const foldingRangeFeature = new FoldingRangeFeature(this);
          foldingRangeFeature['asFoldingRanges'] = MonacoLanguageClient.bypassConversion;
          this.registerFeature(foldingRangeFeature);
          this.registerFeature(new DeclarationFeature(this));
  
          const features = this['_features'] as ((StaticFeature | DynamicFeature<any>)[]);
          for (const feature of features) {
              if (feature instanceof ColorProviderFeature) {
                  feature['asColor'] = MonacoLanguageClient.bypassConversion;
                  feature['asColorInformations'] = MonacoLanguageClient.bypassConversion;
                  feature['asColorPresentations'] = MonacoLanguageClient.bypassConversion;
              }
          }
      }
  
      public registerProposedFeatures() {
          this.registerFeature(new CallHierarchyFeature(this));
          this.registerFeature(new SemanticTokensFeature(this));
      }
  
  }
  export namespace MonacoLanguageClient {
      export interface Options {
          name: string;
          id?: string;
          clientOptions: LanguageClientOptions;
          connectionProvider: IConnectionProvider;
      }
  }
  