/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 5 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* Ġ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 Ġorg . jetbrains . kotlin . generators . protobuf Ċ Ċ import Ġcom . intellij . execution . configurations . General CommandLine Ċ import Ġcom . intellij . execution . util . Exec Util Ċ import Ġcom . intellij . util . Line Separator Ċ import Ġjava . io . File Ċ import Ġjava . util . regex . Pattern Ċ import Ġkotlin . system . exit Process Ċ Ċ // ĠThis Ġfile Ġgenerates Ġprotobuf Ġclasses Ġfrom Ġformal Ġdescription . Ċ // ĠTo Ġrun Ġit , Ġyou 'll Ġneed Ġproto c Ġ( protobuf Ġcompiler ) Ġ 2 . 6 . 1 Ġinstalled . Ċ // Ċ // Ġ* ĠWindows : Ġdownload Ġand Ġunpack Ġfrom Ġhere : Ġhttps :// code . google . com / p / protobuf / downloads / list Ċ // Ġ* ĠUbuntu : Ġinstall Ġ" protobuf - compiler " Ġpackage Ċ // Ġ* ĠmacOS : Ċ // ĠĠĠĠ Ġbrew Ġinstall Ġhttps :// raw . githubusercontent . com / ud al ov / protobuf 2 6 1 / master / protobuf 2 6 1 . rb Ċ // Ġ* ĠYou Ġcan Ġalso Ġdownload Ġsource Ġand Ġbuild Ġit Ġyourself Ġ( https :// code . google . com / p / protobuf / downloads / list ) Ċ // Ċ // ĠYou Ġmay Ġneed Ġto Ġprovide Ġcustom Ġpath Ġto Ġproto c Ġexecutable , Ġjust Ġmodify Ġthis Ġconstant : Ċ private Ġconst Ġval ĠPRO TOC _ EXE Ġ= Ġ" protoc " Ċ Ċ class ĠProto Path ( val Ġfile : ĠString , Ġval Ġgenerate Debug : ĠBoolean Ġ= Ġtrue ) Ġ{ ĊĠĠĠ Ġval Ġout Path : ĠString Ġ= ĠFile ( file ). parent ĊĠĠĠ Ġval ĠpackageName : ĠString Ġ= Ġfind First ( Pattern . compile (" package Ġ(. + ); ")) ĊĠĠĠ Ġval ĠclassName : ĠString Ġ= Ġfind First ( Pattern . compile (" option Ġjava _ outer _ classname Ġ= Ġ\" (. +)\ "; ")) ĊĠĠĠ Ġval Ġdebug ClassName : ĠString Ġ= Ġ" Debug $ className " ĊĊĠĠĠ Ġprivate Ġfun Ġfind First ( pattern : ĠPattern ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( line Ġin ĠFile ( file ). read Lines ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm Ġ= Ġpattern . matcher ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m . find ()) Ġreturn Ġm . group ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġerror (" Pattern Ġnot Ġfound Ġin Ġ$ file : Ġ$ pattern ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ val ĠPROTO _ PATHS : ĠList < Proto Path > Ġ= ĠlistOf ( ĊĠĠĠ ĠProto Path (" core / metadata / src / metadata . proto "), ĊĠĠĠ ĠProto Path (" core / metadata / src / builtins . proto "), ĊĠĠĠ ĠProto Path (" js / js . serializer / src / js . proto "), ĊĠĠĠ ĠProto Path (" js / js . serializer / src / js - ast . proto ", Ġfalse ), ĊĠĠĠ ĠProto Path (" core / metadata . jvm / src / jvm _ metadata . proto "), ĊĠĠĠ ĠProto Path (" core / metadata . jvm / src / jvm _ module . proto "), ĊĠĠĠ ĠProto Path (" build - common / src / java _ descriptors . proto "), ĊĠĠĠ ĠProto Path (" compiler / util - k lib - metadata / src / K lib Metadata Proto Buf . proto ", Ġfalse ), ĊĠĠĠ ĠProto Path (" compiler / ir / serialization . common / src / Kotlin Ir . proto ", Ġfalse ) Ċ ) Ċ Ċ private Ġval ĠEXT _ OPTIONS _ PROTO _ PATH Ġ= ĠProto Path (" core / metadata / src / ext _ options . proto ") Ċ private Ġval ĠPROTO BUF _ PROTO _ PATHS Ġ= ĠlistOf ("./ ", Ġ" core / metadata / src ") Ċ Ċ fun Ġmain () Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Version () ĊĊĠĠĠĠĠĠĠ Ġmodify And Exec Proto c ( EXT _ OPTIONS _ PROTO _ PATH ) ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( proto Path Ġin ĠPROTO _ PATHS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexec Proto c ( proto Path . file , Ġproto Path . out Path ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrename Packages ( proto Path . file , Ġproto Path . out Path ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodify And Exec Proto c ( proto Path ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprintln () ĊĠĠĠĠĠĠĠ Ġprintln (" Do Ġnot Ġforget Ġto Ġrun ĠGenerate Proto Buf Compare ") ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠWork around Ġfor ĠJVM Ġh anging : ĠIDEA 's Ġprocess Ġhandler Ġcreates Ġthread Ġpool ĊĠĠĠĠĠĠĠ Ġexit Process ( 0 ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġcheck Version () Ġ{ ĊĠĠĠ Ġval Ġprocess Output Ġ= ĠExec Util . exec AndGet Output ( General CommandLine ( PROTO C _ EXE , Ġ"-- version ")) ĊĊĠĠĠ Ġval Ġversion Ġ= Ġprocess Output . stdout . trim () ĊĠĠĠ Ġif Ġ( version . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠAssertionError (" Output Ġis Ġempty , Ġstderr : Ġ${ process Output . stderr }") ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( version Ġ!= Ġ" lib protoc Ġ 2 . 6 . 1 ") Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠAssertionError (" Expected Ġproto c Ġ 2 . 6 . 1 , Ġbut Ġwas : Ġ$ version ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġexec Proto c ( proto Path : ĠString , Ġout Path : ĠString ) Ġ{ ĊĠĠĠ Ġval Ġcommand Line Ġ= ĠGeneral CommandLine ( ĊĠĠĠĠĠĠĠ ĠlistOf ( PROTO C _ EXE , Ġproto Path , Ġ"-- java _ out =$ out Path ") Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPROTO BUF _ PROTO _ PATHS . map Ġ{ Ġ"-- proto _ path =$ it " Ġ} ĊĠĠĠ Ġ) ĊĠĠĠ Ġprintln (" running Ġ$ command Line ") ĊĠĠĠ Ġval Ġprocess Output Ġ= ĠExec Util . exec AndGet Output ( command Line ) ĊĠĠĠ Ġprint ( process Output . stdout ) ĊĠĠĠ Ġif Ġ( process Output . stderr . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠAssertionError ( process Output . stderr ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġrename Packages ( proto Path : ĠString , Ġout Path : ĠString ) Ġ{ ĊĠĠĠ Ġfun ĠList < String >. find Value ( regex : ĠRegex ): ĠString ? Ġ= ĊĠĠĠĠĠĠĠ Ġmap NotNull Ġ{ Ġline Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġregex . find ( line )?. group Values ?. get ( 1 ) ĊĠĠĠĠĠĠĠ Ġ}. single OrNull () ĊĊĠĠĠ Ġval Ġproto File Contents Ġ= ĠFile ( proto Path ). read Lines () ĊĠĠĠ Ġval ĠpackageName Ġ= Ġproto File Contents . find Value (" package Ġ([ \\ w . ]+ ); ". to Regex ()) ĊĠĠĠĠĠĠĠ Ġ?: Ġerror (" No Ġpackage Ġdirective Ġfound Ġin Ġ$ proto Path ") ĊĠĠĠ Ġval ĠclassName Ġ= Ġproto File Contents . find Value (" option Ġjava _ outer _ classname Ġ= Ġ\" (\\ w +)\ "; ". to Regex ()) ĊĠĠĠĠĠĠĠ Ġ?: Ġerror (" No Ġjava _ outer _ classname Ġoption Ġfound Ġin Ġ$ proto Path ") ĊĊĠĠĠ Ġval Ġjava Multiple Files Ġ= Ġproto File Contents . find Value (" option Ġjava _ multiple _ files Ġ= Ġ( \\ w + ); ". to Regex ()) Ġ== Ġ" true " ĊĊĠĠĠ Ġif Ġ( java Multiple Files ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpackage Directory Ġ= ĠFile ( out Path , ĠpackageName . replace ('.', Ġ'/ ')) ĊĠĠĠĠĠĠĠ Ġif Ġ(! package Directory . exists () Ġ|| Ġ! package Directory . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAssertionError ("$ proto Path , Ġjava _ multiple _ files Ġmode : Ġ'$ package Directory ' Ġdoesn 't Ġexist Ġor Ġis Ġnot Ġa Ġdirectory ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġjava Files Ġ= Ġpackage Directory . list Files Ġ{ Ġf : ĠFile Ġ-> Ġf . extension Ġ== Ġ" java " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠAssertionError ("$ proto Path , Ġjava _ multiple _ files Ġmode : ĠCan 't Ġlist Ġdirectory Ġcontents Ġof Ġ'$ package Directory '") ĊĠĠĠĠĠĠĠ Ġfor Ġ( java File Ġin Ġjava Files ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrename Packages In Single File ( java File ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġrename Packages In Single File ( File ( out Path , Ġ"${ packageName . replace ('.', Ġ'/') }/ $ className . java ")) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġrename Packages In Single File ( java File : ĠFile ) Ġ{ ĊĠĠĠ Ġif Ġ(! java File . exists ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠAssertionError (" File Ġdoes Ġnot Ġexist : Ġ$ java File ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġjava File . write Text ( ĊĠĠĠĠĠĠĠ Ġjava File . read Lines (). join ToString ( Line Separator . getSystem Line Separator (). separator String ) Ġ{ Ġline Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġline . replace (" com . google . protobuf ", Ġ" org . jetbrains . kotlin . protobuf ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMemory Ġfoot print Ġoptimizations : Ġdo Ġnot Ġallocate Ġtoo Ġbig Ġbytes Ġbuffers Ġthat Ġeffectively Ġremain Ġunused ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace (" ĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠunknownFields Output ); ", Ġ" ĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠunknownFields Output , Ġ 1 ); ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ) Ċ } Ċ Ċ private Ġfun Ġmodify And Exec Proto c ( proto Path : ĠProto Path ) Ġ{ ĊĠĠĠ Ġif Ġ( proto Path . generate Debug ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdebug Proto File Ġ= ĠFile ( proto Path . file . replace (". proto ", Ġ". debug . proto ")) ĊĠĠĠĠĠĠĠ Ġdebug Proto File . write Text ( modify For Debug ( proto Path )) ĊĠĠĠĠĠĠĠ Ġdebug Proto File . delete On Exit () ĊĊĠĠĠĠĠĠĠ Ġval Ġout Path Ġ= Ġ" build - common / test " ĊĠĠĠĠĠĠĠ Ġexec Proto c ( debug Proto File . path , Ġout Path ) ĊĠĠĠĠĠĠĠ Ġrename Packages ( debug Proto File . path , Ġout Path ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġmodify For Debug ( proto Path : ĠProto Path ): ĠString Ġ{ ĊĠĠĠ Ġvar Ġtext Ġ= ĠFile ( proto Path . file ). read Text () ĊĠĠĠĠĠĠĠ Ġ. replace ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" option Ġjava _ outer _ classname Ġ= Ġ\" ${ proto Path . className } \"", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" option Ġjava _ outer _ classname Ġ= Ġ\" ${ proto Path . debug ClassName }\ "" ĊĠĠĠĠĠĠĠ Ġ) Ġ// Ġgive Ġdifferent Ġname Ġfor Ġclass ĊĠĠĠĠĠĠĠ Ġ. replace (" option Ġoptimize _ for Ġ= ĠL ITE _ RUNTIME ;", Ġ"") Ġ// Ġusing Ġdefault Ġinstead ĊĠĠĠ Ġ( listOf ( EXT _ OPTIONS _ PROTO _ PATH ) Ġ+ ĠPROTO _ PATHS ). forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġit . file ĊĠĠĠĠĠĠĠ Ġval Ġnew File Ġ= Ġfile . replace (". proto ", Ġ". debug . proto ") ĊĠĠĠĠĠĠĠ Ġtext Ġ= Ġtext . replace ( file , Ġnew File ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġtext Ċ } Ċ