/********************************************************************************
 * Copyright (C) 2017 TypeFox and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License v. 2.0 are satisfied: GNU General Public License, version 2
 * with the GNU Classpath Exception which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 ********************************************************************************/ import { injectable , inject } from 'inversify' ; import { MessageClient , MessageType , MessageOptions , Progress , ProgressUpdate , ProgressMessage } from './message-service-protocol' ; import { CancellationTokenSource } from './cancellation' ; export const MessageServiceFactory = Symbol ( 'MessageServiceFactory' ) ; /**
 * Service to log and categorize messages, show progress information and offer actions.
 *
 * The messages are processed by this service and forwarded to an injected  MessageClient .
 * For example "@theia/messages" provides such a client, rendering messages as notifications
 * in the frontend.
 *
 * ### Example usage
 *
 * ```typescript
 *    inject @ injectable ( ) export class MessageService { constructor ( @ inject ( MessageClient ) protected readonly client ) { } param message param actions returns log < T extends string > ( message , ... actions ) ; param message param options param actions returns log < T extends string > ( message , options ? , ... actions ) ; log ( message , ... args ) { return this . processMessage ( MessageType . Log , message , args ) ; } param message param actions returns info < T extends string > ( message , ... actions ) ; param message param options param actions returns info < T extends string > ( message , options ? , ... actions ) ; info ( message , ... args ) { return this . processMessage ( MessageType . Info , message , args ) ; } param message param actions returns warn < T extends string > ( message , ... actions ) ; param message param options param actions returns warn < T extends string > ( message , options ? , ... actions ) ; warn ( message , ... args ) { return this . processMessage ( MessageType . Warning , message , args ) ; } param message param actions returns error < T extends string > ( message , ... actions ) ; param message param options param actions returns error < T extends string > ( message , options ? , ... actions ) ; error ( message , ... args ) { return this . processMessage ( MessageType . Error , message , args ) ; } protected processMessage ( type , text , args ? ) { if ( ! ! args && args . length > 0 ) { const first = args [ 0 ] ; const actions = Array . from ( new Set < string > ( args . filter ( a => typeof a === 'string' ) ) ) ; const options = ( typeof first === 'object' && ! Array . isArray ( first ) ) ? < MessageOptions > first : undefined ; return this . client . showMessage ( { type , options , text , actions } ) ; } return this . client . showMessage ( { type , text } ) ; } param message param onDidCancel returns a promise resolving to a  Progress object with which the progress can be updated.
     *
     * ### Example usage
     *
     * ```typescript
     *    inject async showProgress ( message , onDidCancel ? ) { const id = this . newProgressId ( ) ; const cancellationSource = new CancellationTokenSource ( ) ; const report = ( update ) => { this . client . reportProgress ( id , update , message , cancellationSource . token ) ; } ; const actions = new Set < string > ( message . actions ) ; if ( ProgressMessage . isCancelable ( message ) ) { actions . delete ( ProgressMessage . Cancel ) ; actions . add ( ProgressMessage . Cancel ) ; } const clientMessage = { ... message , actions : Array . from ( actions ) } ; const result = this . client . showProgress ( id , clientMessage , cancellationSource . token ) ; if ( ProgressMessage . isCancelable ( message ) && typeof onDidCancel === 'function' ) { result . then ( value => { if ( value === ProgressMessage . Cancel ) { onDidCancel ( ) ; } } ) ; } return { id , cancel : ( ) => cancellationSource . cancel ( ) , result , report } ; } private progressIdPrefix = Math . random ( ) . toString ( 36 ) . substring ( 5 ) ; private counter = 0 ; protected newProgressId ( ) { return `${ this . progressIdPrefix }-${ ++ this . counter }` ; } }