/* Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠThe ĠB azel ĠAuthors . ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* Ġ ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġ Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* Ġ ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* Ġ ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġ Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ* Ċ Ġ*/ Ċ package Ġio . bazel . kotlin . builder . toolchain Ċ Ċ import Ġcom . google . protobuf . Message OrBuilder Ċ import Ġcom . google . protobuf . Text Format Ċ import Ġio . bazel . kotlin . model . Compilation Task Info Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . File Ċ import Ġjava . io . Print Stream Ċ import Ġjava . nio . file . FileSystem s Ċ Ċ class ĠCompilation Task Context ( ĊĠ Ġval Ġinfo : ĠCompilation Task Info , ĊĠ Ġprivate Ġval Ġout : ĠPrint Stream , ĊĠ Ġprivate Ġval Ġexecution Root : ĠString Ġ= ĠFileSystem s . getDefault (). getPath (" "). to AbsolutePath () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toString () Ġ+ ĠFile . separator Ċ ) Ġ{ ĊĠ Ġprivate Ġval Ġstart Ġ= ĠSystem . currentTimeMillis () ĊĠ Ġprivate Ġvar Ġtim ings : ĠMutable List < String >? ĊĠ Ġprivate Ġvar Ġlevel Ġ= Ġ- 1 ĊĠ Ġprivate Ġval Ġis Tracing : ĠBoolean ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġval Ġdebugging Ġ= Ġinfo . debug List . toSet () ĊĠĠĠ Ġtim ings Ġ= Ġif Ġ( debugging . contains (" tim ings ")) Ġmutable ListOf () Ġelse Ġnull ĊĠĠĠ Ġis Tracing Ġ= Ġdebugging . contains (" trace ") ĊĠ Ġ} ĊĊĠ Ġfun Ġreport Unhandled Exception ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠ Ġthrowable . printStackTrace ( out ) ĊĠ Ġ} ĊĊĠ Ġ@ Suppress (" unused ") ĊĠ Ġfun Ġprint ( msg : ĠString ) Ġ{ ĊĠĠĠ Ġout . println ( msg ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠPrint Ġa Ġlist Ġof Ġdebugging Ġlines . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġheader Ġa Ġheader Ġstring ĊĠĠ Ġ* Ġ@ param Ġlines Ġa Ġlist Ġof Ġlines Ġto Ġprint Ġout ĊĠĠ Ġ* Ġ@ param Ġprefix Ġa Ġprefix Ġto Ġadd Ġto Ġeach Ġline ĊĠĠ Ġ* Ġ@ param Ġfilter Empty Ġif Ġempty Ġlines Ġshould Ġbe Ġdiscarded Ġor Ġnot ĊĠĠ Ġ*/ ĊĠ Ġfun Ġprint Lines ( ĊĠĠĠ Ġheader : ĠString , ĊĠĠĠ Ġlines : ĠList < String >, ĊĠĠĠ Ġprefix : ĠString Ġ= Ġ"| Ġ Ġ", ĊĠĠĠ Ġfilter Empty : ĠBoolean Ġ= Ġfalse ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġcheck ( header . isNotEmpty ()) ĊĠĠĠ Ġout . println ( if Ġ( header . endsWith (" :" )) Ġheader Ġelse Ġ"$ header :") ĊĠĠĠ Ġlines . forEach Ġ{ ĊĠĠĠĠĠ Ġif Ġ( it . isNotEmpty () Ġ|| Ġ! filter Empty ) Ġ{ ĊĠĠĠĠĠĠĠ Ġout . println ("$ prefix $ it ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġout . println () ĊĠ Ġ} ĊĊĠ Ġfun Ġ< T > Ġwhen Tracing ( block : ĠCompilation Task Context . () Ġ-> ĠT ): ĠT ? Ġ{ ĊĠĠĠ Ġreturn Ġif Ġ( is Tracing ) Ġ{ ĊĠĠĠĠĠ Ġblock () ĊĠĠĠ Ġ} Ġelse Ġnull ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠPrint Ġa Ġproto Ġmessage Ġif Ġdebugging Ġis Ġenabled Ġfor Ġthe Ġtask . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġprint Proto ( header : ĠString , Ġmsg : ĠMessage OrBuilder ) Ġ{ ĊĠĠĠ Ġprint Lines ( header , ĠText Format . print ToString ( msg ). split ("\ n "), Ġfilter Empty Ġ= Ġtrue ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠThis Ġmethod Ġnormal izes Ġand Ġreports Ġthe Ġoutput Ġfrom Ġthe ĠKotlin Ġcompiler . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġprint Compiler Output ( lines : ĠList < String >) Ġ{ ĊĠĠĠ Ġlines . map (:: trim Execution Root Prefix ). forEach ( out :: println ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġtrim Execution Root Prefix ( to Print : ĠString ): ĠString Ġ{ ĊĠĠĠ Ġ// Ġtrim Ġoff Ġthe Ġworkspace Ġcomponent ĊĠĠĠ Ġreturn Ġif Ġ( to Print . startsWith ( execution Root )) Ġ{ ĊĠĠĠĠĠ Ġto Print . replace First ( execution Root , Ġ"") ĊĠĠĠ Ġ} Ġelse Ġto Print ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠExecute Ġa Ġcompilation Ġtask . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ throws ĠCompilation Status Exception Ġif Ġthe Ġcompiler Ġreturns Ġa Ġstatus Ġof Ġanything Ġbut Ġzero . ĊĠĠ Ġ* Ġ@ param Ġargs Ġthe Ġcompiler Ġcommand Ġline Ġswitches ĊĠĠ Ġ* Ġ@ param Ġprint On Fail Ġif Ġthis Ġis Ġtrue Ġthe Ġoutput Ġwill Ġbe Ġprinted Ġif Ġthe Ġtask Ġfails Ġelse Ġthe Ġcaller Ġis Ġresponsible ĊĠĠ Ġ* Ġ Ġfor Ġlogging Ġit Ġby Ġcatch ing Ġthe Ġ[ Compilation Status Exception ] Ġexception . ĊĠĠ Ġ* Ġ@ param Ġcompile Ġthe Ġcompilation Ġmethod . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġexecute Compiler Task ( ĊĠĠĠ Ġargs : ĠList < String >, ĊĠĠĠ Ġcompile : Ġ( Array < String >, ĠPrint Stream ) Ġ-> ĠInt , ĊĠĠĠ Ġprint On Fail : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġprint On Success : ĠBoolean Ġ= Ġtrue ĊĠ Ġ): ĠList < String > Ġ{ ĊĠĠĠ Ġval ĠoutputStream Ġ= ĠByteArrayOutputStream () ĊĠĠĠ Ġval Ġps Ġ= ĠPrint Stream ( output Stream ) ĊĠĠĠ Ġval Ġresult Ġ= Ġcompile ( args . to Typed Array (), Ġps ) ĊĠĠĠ Ġval Ġoutput Ġ= ĠByteArrayInputStream ( output Stream . toByteArray ()) ĊĠĠĠĠĠ Ġ. buffered Reader () ĊĠĠĠĠĠ Ġ. read Lines () ĊĠĠĠ Ġif Ġ( result Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( print On Fail ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprint Compiler Output ( output ) ĊĠĠĠĠĠĠĠ Ġthrow ĠCompilation Status Exception (" compile Ġphase Ġfailed ", Ġresult ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġthrow ĠCompilation Status Exception (" compile Ġphase Ġfailed ", Ġresult , Ġoutput ) ĊĠĠĠ Ġ} Ġelse Ġif Ġ( print On Success ) Ġ{ ĊĠĠĠĠĠ Ġprint Compiler Output ( output ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġoutput ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠRuns Ġa Ġtask Ġand Ġrecords Ġthe Ġtim ings . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġ< T > Ġexecute ( name : ĠString , Ġtask : Ġ() Ġ-> ĠT ): ĠT Ġ= Ġexecute ({ Ġname Ġ}, Ġtask ) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠRuns Ġa Ġtask Ġand Ġrecords Ġthe Ġtim ings . ĊĠĠ Ġ*/ ĊĠ Ġ@ Suppress (" Member Visibility Can Be Private ") ĊĠ Ġfun Ġ< T > Ġexecute ( name : Ġ() Ġ-> ĠString , Ġtask : Ġ() Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠ Ġreturn Ġif Ġ( tim ings Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġtask () ĊĠĠĠ Ġ} Ġelse Ġpush Timed Task ( name (), Ġtask ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġinline Ġfun Ġ< T > Ġpush Timed Task ( name : ĠString , Ġtask : Ġ() Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠ Ġlevel Ġ+= Ġ 1 ĊĠĠĠ Ġval Ġprevious Tim ings Ġ= Ġtim ings ĊĠĠĠ Ġtim ings Ġ= Ġmutable ListOf () ĊĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠ ĠSystem . currentTimeMillis (). let Ġ{ Ġstart Ġ-> ĊĠĠĠĠĠĠĠ Ġtask (). also Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġstop Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠ Ġprevious Tim ings !! Ġ+= Ġ"${ " Ġ Ġ". repeat ( level )} Ġ* Ġ$ name : Ġ${ stop Ġ- Ġstart } Ġms " ĊĠĠĠĠĠĠĠĠĠ Ġprevious Tim ings . addAll ( tim ings !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠ Ġlevel Ġ-= Ġ 1 ĊĠĠĠĠĠ Ġtim ings Ġ= Ġprevious Tim ings ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠThis Ġmethod Ġshould Ġbe Ġcalled Ġat Ġthe Ġend Ġof Ġbuilder Ġinvocation . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġsuccessful Ġtrue Ġif Ġthe Ġtask Ġfinished Ġsuccessfully . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġfinalize ( successful : ĠBoolean ) Ġ{ ĊĠĠĠ Ġif Ġ( successful ) Ġ{ ĊĠĠĠĠĠ Ġtim ings ?. also Ġ{ ĊĠĠĠĠĠĠĠ Ġprint Lines ( ĊĠĠĠĠĠĠĠĠĠ Ġ" Task Ġtim ings Ġfor Ġ${ info . label } Ġ( total : Ġ${ System . currentTimeMillis () Ġ- Ġstart } Ġms )", Ġit ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ