diff --git a/generators/tests/org/jetbrains/kotlin/generators/protobuf/GenerateProtoBuf.kt b/generators/tests/org/jetbrains/kotlin/generators/protobuf/GenerateProtoBuf.kt index 08ce35b4144..63a2b121b11 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/protobuf/GenerateProtoBuf.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/protobuf/GenerateProtoBuf.kt @@ -51,22 +51,22 @@ class ProtoPath(val file: String, val generateDebug: Boolean = true) { } val PROTO_PATHS: List = listOf( - ProtoPath("core/metadata/src/metadata.proto"), - ProtoPath("core/metadata/src/builtins.proto"), - ProtoPath("js/js.serializer/src/js.proto"), - ProtoPath("js/js.serializer/src/js-ast.proto", false), - ProtoPath("konan/library-reader/src/konan.proto"), - ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"), - ProtoPath("core/metadata.jvm/src/jvm_module.proto"), - ProtoPath("build-common/src/java_descriptors.proto"), - ProtoPath("compiler/ir/backend.js/src/js.proto", false), - ProtoPath("compiler/ir/serialization.common/src/KotlinIr.proto", false) + ProtoPath("core/metadata/src/metadata.proto"), + ProtoPath("core/metadata/src/builtins.proto"), + ProtoPath("js/js.serializer/src/js.proto"), + ProtoPath("js/js.serializer/src/js-ast.proto", false), + ProtoPath("konan/library-reader/src/konan.proto"), + ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"), + ProtoPath("core/metadata.jvm/src/jvm_module.proto"), + ProtoPath("build-common/src/java_descriptors.proto"), + ProtoPath("compiler/ir/backend.js/src/js.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 PROTOBUF_PROTO_PATHS = listOf("./", "core/metadata/src") -fun main(args: Array) { +fun main() { try { checkVersion() @@ -80,12 +80,10 @@ fun main(args: Array) { println() println("Do not forget to run GenerateProtoBufCompare") - } - catch (e: Throwable) { + } catch (e: Throwable) { e.printStackTrace() throw e - } - finally { + } finally { // Workaround for JVM hanging: IDEA's process handler creates thread pool exitProcess(0) } @@ -105,8 +103,8 @@ private fun checkVersion() { private fun execProtoc(protoPath: String, outPath: String) { val commandLine = GeneralCommandLine( - listOf(PROTOC_EXE, protoPath, "--java_out=$outPath") + - PROTOBUF_PROTO_PATHS.map { "--proto_path=$it" } + listOf(PROTOC_EXE, protoPath, "--java_out=$outPath") + + PROTOBUF_PROTO_PATHS.map { "--proto_path=$it" } ) println("running $commandLine") val processOutput = ExecUtil.execAndGetOutput(commandLine) @@ -118,27 +116,44 @@ private fun execProtoc(protoPath: String, outPath: String) { private fun renamePackages(protoPath: String, outPath: String) { fun List.findValue(regex: Regex): String? = - mapNotNull { line -> - regex.find(line)?.groupValues?.get(1) - }.singleOrNull() + mapNotNull { line -> + regex.find(line)?.groupValues?.get(1) + }.singleOrNull() val protoFileContents = File(protoPath).readLines() 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()) - ?: 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()) { throw AssertionError("File does not exist: $javaFile") } javaFile.writeText( - javaFile.readLines().map { line -> - line.replace("com.google.protobuf", "org.jetbrains.kotlin.protobuf") - // Memory footprint optimizations: do not allocate too big bytes buffers that effectively remain unused - .replace(" unknownFieldsOutput);", " unknownFieldsOutput, 1);") - }.joinToString(LineSeparator.getSystemLineSeparator().separatorString) + javaFile.readLines().joinToString(LineSeparator.getSystemLineSeparator().separatorString) { line -> + line.replace("com.google.protobuf", "org.jetbrains.kotlin.protobuf") + // Memory footprint optimizations: do not allocate too big bytes buffers that effectively remain unused + .replace(" unknownFieldsOutput);", " unknownFieldsOutput, 1);") + } ) } @@ -156,9 +171,11 @@ private fun modifyAndExecProtoc(protoPath: ProtoPath) { private fun modifyForDebug(protoPath: ProtoPath): String { var text = File(protoPath.file).readText() - .replace("option java_outer_classname = \"${protoPath.className}\"", - "option java_outer_classname = \"${protoPath.debugClassName}\"") // give different name for class - .replace("option optimize_for = LITE_RUNTIME;", "") // using default instead + .replace( + "option java_outer_classname = \"${protoPath.className}\"", + "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 { val file = it.file val newFile = file.replace(".proto", ".debug.proto")