GenerateProtoBuf: support java_multiple_files mode
This commit is contained in:
@@ -51,22 +51,22 @@ class ProtoPath(val file: String, val generateDebug: Boolean = true) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val PROTO_PATHS: List<ProtoPath> = listOf(
|
val PROTO_PATHS: List<ProtoPath> = listOf(
|
||||||
ProtoPath("core/metadata/src/metadata.proto"),
|
ProtoPath("core/metadata/src/metadata.proto"),
|
||||||
ProtoPath("core/metadata/src/builtins.proto"),
|
ProtoPath("core/metadata/src/builtins.proto"),
|
||||||
ProtoPath("js/js.serializer/src/js.proto"),
|
ProtoPath("js/js.serializer/src/js.proto"),
|
||||||
ProtoPath("js/js.serializer/src/js-ast.proto", false),
|
ProtoPath("js/js.serializer/src/js-ast.proto", false),
|
||||||
ProtoPath("konan/library-reader/src/konan.proto"),
|
ProtoPath("konan/library-reader/src/konan.proto"),
|
||||||
ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"),
|
ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"),
|
||||||
ProtoPath("core/metadata.jvm/src/jvm_module.proto"),
|
ProtoPath("core/metadata.jvm/src/jvm_module.proto"),
|
||||||
ProtoPath("build-common/src/java_descriptors.proto"),
|
ProtoPath("build-common/src/java_descriptors.proto"),
|
||||||
ProtoPath("compiler/ir/backend.js/src/js.proto", false),
|
ProtoPath("compiler/ir/backend.js/src/js.proto", false),
|
||||||
ProtoPath("compiler/ir/serialization.common/src/KotlinIr.proto", false)
|
ProtoPath("compiler/ir/serialization.common/src/KotlinIr.proto", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val EXT_OPTIONS_PROTO_PATH = ProtoPath("core/metadata/src/ext_options.proto")
|
private val EXT_OPTIONS_PROTO_PATH = ProtoPath("core/metadata/src/ext_options.proto")
|
||||||
private val PROTOBUF_PROTO_PATHS = listOf("./", "core/metadata/src")
|
private val PROTOBUF_PROTO_PATHS = listOf("./", "core/metadata/src")
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main() {
|
||||||
try {
|
try {
|
||||||
checkVersion()
|
checkVersion()
|
||||||
|
|
||||||
@@ -80,12 +80,10 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
println()
|
println()
|
||||||
println("Do not forget to run GenerateProtoBufCompare")
|
println("Do not forget to run GenerateProtoBufCompare")
|
||||||
}
|
} catch (e: Throwable) {
|
||||||
catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
throw e
|
throw e
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
// Workaround for JVM hanging: IDEA's process handler creates thread pool
|
// Workaround for JVM hanging: IDEA's process handler creates thread pool
|
||||||
exitProcess(0)
|
exitProcess(0)
|
||||||
}
|
}
|
||||||
@@ -105,8 +103,8 @@ private fun checkVersion() {
|
|||||||
|
|
||||||
private fun execProtoc(protoPath: String, outPath: String) {
|
private fun execProtoc(protoPath: String, outPath: String) {
|
||||||
val commandLine = GeneralCommandLine(
|
val commandLine = GeneralCommandLine(
|
||||||
listOf(PROTOC_EXE, protoPath, "--java_out=$outPath") +
|
listOf(PROTOC_EXE, protoPath, "--java_out=$outPath") +
|
||||||
PROTOBUF_PROTO_PATHS.map { "--proto_path=$it" }
|
PROTOBUF_PROTO_PATHS.map { "--proto_path=$it" }
|
||||||
)
|
)
|
||||||
println("running $commandLine")
|
println("running $commandLine")
|
||||||
val processOutput = ExecUtil.execAndGetOutput(commandLine)
|
val processOutput = ExecUtil.execAndGetOutput(commandLine)
|
||||||
@@ -118,27 +116,44 @@ private fun execProtoc(protoPath: String, outPath: String) {
|
|||||||
|
|
||||||
private fun renamePackages(protoPath: String, outPath: String) {
|
private fun renamePackages(protoPath: String, outPath: String) {
|
||||||
fun List<String>.findValue(regex: Regex): String? =
|
fun List<String>.findValue(regex: Regex): String? =
|
||||||
mapNotNull { line ->
|
mapNotNull { line ->
|
||||||
regex.find(line)?.groupValues?.get(1)
|
regex.find(line)?.groupValues?.get(1)
|
||||||
}.singleOrNull()
|
}.singleOrNull()
|
||||||
|
|
||||||
val protoFileContents = File(protoPath).readLines()
|
val protoFileContents = File(protoPath).readLines()
|
||||||
val packageName = protoFileContents.findValue("package ([\\w.]+);".toRegex())
|
val packageName = protoFileContents.findValue("package ([\\w.]+);".toRegex())
|
||||||
?: error("No package directive found in $protoPath")
|
?: error("No package directive found in $protoPath")
|
||||||
val className = protoFileContents.findValue("option java_outer_classname = \"(\\w+)\";".toRegex())
|
val className = protoFileContents.findValue("option java_outer_classname = \"(\\w+)\";".toRegex())
|
||||||
?: error("No java_outer_classname option found in $protoPath")
|
?: error("No java_outer_classname option found in $protoPath")
|
||||||
|
|
||||||
val javaFile = File(outPath, "${packageName.replace('.', '/')}/$className.java")
|
val javaMultipleFiles = protoFileContents.findValue("option java_multiple_files = (\\w+);".toRegex()) == "true"
|
||||||
|
|
||||||
|
if (javaMultipleFiles) {
|
||||||
|
val packageDirectory = File(outPath, packageName.replace('.', '/'))
|
||||||
|
if (!packageDirectory.exists() || !packageDirectory.isDirectory) {
|
||||||
|
throw AssertionError("$protoPath, java_multiple_files mode: '$packageDirectory' doesn't exist or is not a directory")
|
||||||
|
}
|
||||||
|
val javaFiles = packageDirectory.listFiles { f: File -> f.extension == "java" }
|
||||||
|
?: throw AssertionError("$protoPath, java_multiple_files mode: Can't list directory contents of '$packageDirectory'")
|
||||||
|
for (javaFile in javaFiles) {
|
||||||
|
renamePackagesInSingleFile(javaFile)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
renamePackagesInSingleFile(File(outPath, "${packageName.replace('.', '/')}/$className.java"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renamePackagesInSingleFile(javaFile: File) {
|
||||||
if (!javaFile.exists()) {
|
if (!javaFile.exists()) {
|
||||||
throw AssertionError("File does not exist: $javaFile")
|
throw AssertionError("File does not exist: $javaFile")
|
||||||
}
|
}
|
||||||
|
|
||||||
javaFile.writeText(
|
javaFile.writeText(
|
||||||
javaFile.readLines().map { line ->
|
javaFile.readLines().joinToString(LineSeparator.getSystemLineSeparator().separatorString) { line ->
|
||||||
line.replace("com.google.protobuf", "org.jetbrains.kotlin.protobuf")
|
line.replace("com.google.protobuf", "org.jetbrains.kotlin.protobuf")
|
||||||
// Memory footprint optimizations: do not allocate too big bytes buffers that effectively remain unused
|
// Memory footprint optimizations: do not allocate too big bytes buffers that effectively remain unused
|
||||||
.replace(" unknownFieldsOutput);", " unknownFieldsOutput, 1);")
|
.replace(" unknownFieldsOutput);", " unknownFieldsOutput, 1);")
|
||||||
}.joinToString(LineSeparator.getSystemLineSeparator().separatorString)
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,9 +171,11 @@ private fun modifyAndExecProtoc(protoPath: ProtoPath) {
|
|||||||
|
|
||||||
private fun modifyForDebug(protoPath: ProtoPath): String {
|
private fun modifyForDebug(protoPath: ProtoPath): String {
|
||||||
var text = File(protoPath.file).readText()
|
var text = File(protoPath.file).readText()
|
||||||
.replace("option java_outer_classname = \"${protoPath.className}\"",
|
.replace(
|
||||||
"option java_outer_classname = \"${protoPath.debugClassName}\"") // give different name for class
|
"option java_outer_classname = \"${protoPath.className}\"",
|
||||||
.replace("option optimize_for = LITE_RUNTIME;", "") // using default instead
|
"option java_outer_classname = \"${protoPath.debugClassName}\""
|
||||||
|
) // give different name for class
|
||||||
|
.replace("option optimize_for = LITE_RUNTIME;", "") // using default instead
|
||||||
(listOf(EXT_OPTIONS_PROTO_PATH) + PROTO_PATHS).forEach {
|
(listOf(EXT_OPTIONS_PROTO_PATH) + PROTO_PATHS).forEach {
|
||||||
val file = it.file
|
val file = it.file
|
||||||
val newFile = file.replace(".proto", ".debug.proto")
|
val newFile = file.replace(".proto", ".debug.proto")
|
||||||
|
|||||||
Reference in New Issue
Block a user