/******************************************************************************
 * Copyright 2021 TypeFox GmbH
 * This program and the accompanying materials are made available under the
 * terms of the MIT License, which is available in the project root.
 ******************************************************************************/ import * as langium from 'langium' ; import { CompositeGeneratorNode , GeneratorNode , NL , stream } from 'langium' ; import fs from 'fs-extra' ; import path from 'path' ; import * as readline from 'readline' ; import type { GenerateOptions } from '../generate' ; export function log ( level , options , message , ... args ) { if ( options . watch ) { console [ level ] ( getTime ( ) + message , ... args ) ; } else { console [ level ] ( message , ... args ) ; } } let start = process . hrtime ( ) ; export function elapsedTime ( ) { const elapsed = process . hrtime ( start ) [ 1 ] / 1000000 ; start = process . hrtime ( ) ; return elapsed . toFixed ( ) ; } export function getTime ( ) { const date = new Date ( ) ; return `[${ `${ padZeroes ( date . getHours ( ) ) }:${ padZeroes ( date . getMinutes ( ) ) }:${ padZeroes ( date . getSeconds ( ) ) }` . gray }] ` ; } function padZeroes ( i ) { return i . toString ( ) . padStart ( 2 , '0' ) ; } function getLangiumCliVersion ( ) { const ownPackagePath = path . resolve ( __dirname , '..' , '..' , 'package.json' ) ; const pack = fs . readJsonSync ( ownPackagePath , { encoding : 'utf-8' } ) ; return pack . version ; } function getGeneratedHeader ( ) { const node = new CompositeGeneratorNode ( ) ; node . contents . push ( '/******************************************************************************' , NL , ` * This file was generated by langium-cli ${ cliVersion }.` , NL , ' * DO NOT EDIT MANUALLY!' , NL , ' ******************************************************************************/' , NL , NL ) ; return node ; } export function collectKeywords ( grammar ) { const keywords = new Set < string > ( ) ; for ( const rule of stream ( grammar . rules ) . filter ( langium . isParserRule ) ) { collectElementKeywords ( rule . alternatives , keywords ) ; } return Array . from ( keywords ) . sort ( ( a , b ) => a . localeCompare ( b ) ) ; } function collectElementKeywords ( element , keywords ) { if ( langium . isAlternatives ( element ) || langium . isGroup ( element ) || langium . isUnorderedGroup ( element ) ) { for ( const item of element . elements ) { collectElementKeywords ( item , keywords ) ; } } else if ( langium . isAssignment ( element ) ) { collectElementKeywords ( element . terminal , keywords ) ; } else if ( langium . isKeyword ( element ) ) { keywords . add ( element . value ) ; } } export function getUserInput ( text ) { return new Promise ( resolve => { const rl = readline . createInterface ( { input : process . stdin , output : process . stdout } ) ; rl . question ( text , answer => { resolve ( answer ) ; rl . close ( ) ; } ) ; } ) ; } export async function getUserChoice < R extends string > ( text , values , defaultValue , lowerCase = true ) { const prompt = text + ' ' + values . map ( v => v === defaultValue ? `[${ v }]` : v ) . join ( '/' ) + ': ' ; const answer = await getUserInput ( prompt ) ; if ( ! answer ) { return defaultValue ; } const lcAnswer = lowerCase ? answer . toLowerCase ( ) : answer ; for ( const value of values ) { if ( value . startsWith ( lcAnswer ) ) { return value ; } } return defaultValue ; } export const cliVersion = getLangiumCliVersion ( ) ; export const generatedHeader = getGeneratedHeader ( ) ; export const schema = fs . readJson ( path . resolve ( __dirname , '../../langium-config-schema.json' ) , { encoding : 'utf-8' } ) ;