Add proper message logging
diff --git a/compiler/incremental-compilation-facade/api/src/main/kotlin/org/jetbrains/kotlin/api/Callbacks.kt b/compiler/incremental-compilation-facade/api/src/main/kotlin/org/jetbrains/kotlin/api/Callbacks.kt
index b57fcb2..15705dc 100644
--- a/compiler/incremental-compilation-facade/api/src/main/kotlin/org/jetbrains/kotlin/api/Callbacks.kt
+++ b/compiler/incremental-compilation-facade/api/src/main/kotlin/org/jetbrains/kotlin/api/Callbacks.kt
@@ -10,5 +10,12 @@
 )
 
 interface MessageLogger {
+    fun report(level: FacadeLogLevel, message: String)
+}
 
+enum class FacadeLogLevel {
+    ERROR,
+    WARNING,
+    INFO,
+    DEBUG,
 }
\ No newline at end of file
diff --git a/compiler/incremental-compilation-facade/impl/src/main/kotlin/org/jetbrains/kotlin/incremental/DefaultIncrementalCompilerFacade.kt b/compiler/incremental-compilation-facade/impl/src/main/kotlin/org/jetbrains/kotlin/incremental/DefaultIncrementalCompilerFacade.kt
index 0d7201e..68d9e789 100644
--- a/compiler/incremental-compilation-facade/impl/src/main/kotlin/org/jetbrains/kotlin/incremental/DefaultIncrementalCompilerFacade.kt
+++ b/compiler/incremental-compilation-facade/impl/src/main/kotlin/org/jetbrains/kotlin/incremental/DefaultIncrementalCompilerFacade.kt
@@ -7,10 +7,12 @@
 
 import org.jetbrains.kotlin.api.*
 import org.jetbrains.kotlin.build.report.DoNothingBuildReporter
+import org.jetbrains.kotlin.cli.common.ExitCode
 import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
 import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
 import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
 import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
 import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
 import org.jetbrains.kotlin.cli.common.messages.MessageCollector
 import org.jetbrains.kotlin.compilerRunner.KotlinCompilerRunnerUtils
@@ -40,19 +42,33 @@
     }
 }
 
-class MessageReporter(private val messageLogger: MessageLogger) : MessageCollector {
-    override fun clear() {
-        TODO("Not yet implemented")
-    }
+class MessageReporter(private val messageLoggerCallback: MessageLogger) : MessageCollector {
+    override fun clear() {}
 
     override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
-        TODO("Not yet implemented")
+        val level = when {
+            severity.isError -> FacadeLogLevel.ERROR.also { hasErrors = true }
+            severity.isWarning -> FacadeLogLevel.WARNING
+            severity == INFO -> FacadeLogLevel.INFO
+            severity == LOGGING || severity == OUTPUT -> FacadeLogLevel.DEBUG
+            else -> error("Unknown message severity: $severity")
+        }
+        val formattedMessage = buildString {
+            location?.apply {
+                val fileUri = File(path).toPath().toUri()
+                append("$fileUri")
+                if (line > 0 && column > 0) {
+                    append(":$line:$column ")
+                }
+            }
+            append(message)
+        }
+        messageLoggerCallback.report(level, formattedMessage)
     }
 
-    override fun hasErrors(): Boolean {
-        TODO("Not yet implemented")
-    }
+    private var hasErrors = false
 
+    override fun hasErrors() = hasErrors
 }
 
 class DefaultIncrementalCompilerFacade : IncrementalCompilerFacade {
@@ -60,12 +76,12 @@
         launchOptions: LaunchOptions.Daemon,
         arguments: List<String>,
         options: org.jetbrains.kotlin.api.CompilationOptions,
-    ) {
+        messageCollector: MessageCollector,
+    ): ExitCode {
         println("Compiling with daemon")
         val compilerId = CompilerId.makeCompilerId(launchOptions.classpath)
         val clientIsAliveFlagFile = File("1")
         val sessionIsAliveFlagFile = File("2")
-        val messageCollector = DumbMessageCollector
 
         val daemonOptions = configureDaemonJVMOptions(
             inheritMemoryLimits = true,
@@ -118,30 +134,43 @@
                 kotlinScriptExtensions = options.kotlinScriptExtensions,
             )
         }
-        daemon.compile(
+        val exitCode = daemon.compile(
             sessionId,
             arguments.toTypedArray(),
             daemonCompileOptions,
             BasicCompilerServicesWithResultsFacadeServer(messageCollector),
             DaemonCompilationResults()
-        )
+        ).get()
+        return ExitCode.values().find { it.code == exitCode } ?: if (exitCode == 0) {
+            ExitCode.OK
+        } else {
+            ExitCode.COMPILATION_ERROR
+        }
     }
 
-    private fun compileInProcess(arguments: List<String>, options: org.jetbrains.kotlin.api.CompilationOptions) {
+    private fun compileInProcess(
+        arguments: List<String>,
+        options: org.jetbrains.kotlin.api.CompilationOptions,
+        messageCollector: MessageCollector,
+    ): ExitCode {
         println("Compiling in-process")
         val compiler = createCompiler(options.targetPlatform)
         val parsedArguments = prepareAndValidateCompilerArguments(compiler, arguments)
-        when (options) {
-            is org.jetbrains.kotlin.api.CompilationOptions.Incremental -> compileIncrementally(parsedArguments, options)
+        return when (options) {
+            is org.jetbrains.kotlin.api.CompilationOptions.Incremental -> compileIncrementally(parsedArguments, options, messageCollector)
             is org.jetbrains.kotlin.api.CompilationOptions.NonIncremental -> compiler.exec(
-                DumbMessageCollector,
+                messageCollector,
                 Services.EMPTY,
                 parsedArguments
             )
         }
     }
 
-    private fun compileIncrementally(args: CommonCompilerArguments, options: org.jetbrains.kotlin.api.CompilationOptions.Incremental) {
+    private fun compileIncrementally(
+        args: CommonCompilerArguments,
+        options: org.jetbrains.kotlin.api.CompilationOptions.Incremental,
+        messageCollector: MessageCollector,
+    ): ExitCode {
         val incrementalCompilerRunner = when (options.targetPlatform) {
             TargetPlatform.JVM -> IncrementalCompilerRunnerWithArgs(
                 args as K2JVMCompilerArguments,
@@ -177,12 +206,12 @@
                 error("Unsupported platform")
             }
         }
-        execIncrementalCompilerRunner(
+        return execIncrementalCompilerRunner(
             incrementalCompilerRunner,
             options.kotlinScriptExtensions?.toList() ?: emptyList(),
             prepareFileChanges(options.areFileChangesKnown, options.modifiedFiles, options.deletedFiles),
             options.modulesInfo.projectRoot,
-            DumbMessageCollector
+            messageCollector
         )
     }
 
@@ -192,9 +221,13 @@
         options: org.jetbrains.kotlin.api.CompilationOptions,
         callbacks: Callbacks,
     ) {
-        when (launchOptions) {
-            is LaunchOptions.Daemon -> compileWithDaemon(launchOptions, arguments, options)
-            is LaunchOptions.InProcess -> compileInProcess(arguments, options)
+        val messageCollector = callbacks.messageLogger?.let { MessageReporter(it) } ?: DumbMessageCollector
+        val exitCode = when (launchOptions) {
+            is LaunchOptions.Daemon -> compileWithDaemon(launchOptions, arguments, options, messageCollector)
+            is LaunchOptions.InProcess -> compileInProcess(arguments, options, messageCollector)
+        }
+        if (exitCode != ExitCode.OK) {
+            throw Exception("Compilation failed")
         }
     }
 }
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleIncrementalCompilationFacadeRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleIncrementalCompilationFacadeRunner.kt
index ec18883..138d1d4 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleIncrementalCompilationFacadeRunner.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleIncrementalCompilationFacadeRunner.kt
@@ -16,17 +16,21 @@
 import org.gradle.workers.WorkQueue
 import org.gradle.workers.WorkerExecutor
 import org.jetbrains.kotlin.api.*
+import org.jetbrains.kotlin.api.FacadeLogLevel.*
 import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
 import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric
 import org.jetbrains.kotlin.build.report.metrics.BuildTime
 import org.jetbrains.kotlin.build.report.metrics.measure
-import org.jetbrains.kotlin.daemon.common.CompilerMode
+import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
+import org.jetbrains.kotlin.gradle.logging.SL4JKotlinLogger
+import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
 import org.jetbrains.kotlin.gradle.tasks.*
 import org.jetbrains.kotlin.gradle.tasks.CompilationErrorException
 import org.jetbrains.kotlin.gradle.tasks.FailedCompilationException
 import org.jetbrains.kotlin.gradle.tasks.OOMErrorException
 import org.jetbrains.kotlin.gradle.tasks.TaskOutputsBackup
 import org.jetbrains.kotlin.incremental.*
+import org.slf4j.LoggerFactory
 import java.io.File
 import java.net.URLClassLoader
 import java.util.*
@@ -119,6 +123,21 @@
             }
         }
 
+        private val taskPath
+            get() = workArguments.taskPath
+        private val log: KotlinLogger =
+            TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } }
+                ?: run {
+                    val logger = LoggerFactory.getLogger("GradleKotlinCompilerWork")
+                    val kotlinLogger = if (logger is org.gradle.api.logging.Logger) {
+                        GradleKotlinLogger(logger)
+                    } else SL4JKotlinLogger(logger)
+
+                    kotlinLogger.apply {
+                        debug("Could not get logger for '$taskPath'. Falling back to sl4j logger")
+                    }
+                }
+
         override fun execute() {
             val taskOutputsBackup = if (parameters.snapshotsDir.isPresent) {
                 TaskOutputsBackup(
@@ -144,7 +163,13 @@
                 val classloader = URLClassLoader(classpath.toList().map { it.toURI().toURL() }.toTypedArray(), parentClassloader)
                 val facade = ServiceLoader.load(IncrementalCompilerFacade::class.java, classloader).singleOrNull()
                     ?: error("Compiler classpath should contain one and only one implementation of ${IncrementalCompilerFacade::class.java.name}")
-                facade.compile(prepareLaunchOptions(), workArguments.compilerArgs.toList(), prepareKotlinCompilerOptions(), Callbacks(null))
+                val messageLogger = GradleFacadeMessageLogger(log, workArguments.allWarningsAsErrors)
+                facade.compile(
+                    prepareLaunchOptions(),
+                    workArguments.compilerArgs.toList(),
+                    prepareKotlinCompilerOptions(),
+                    Callbacks(messageLogger)
+                )
             } catch (e: FailedCompilationException) {
                 // Restore outputs only in cases where we expect that the user will make some changes to their project:
                 //   - For a compilation error, the user will need to fix their source code
@@ -187,4 +212,17 @@
             super.loadClass(name, resolve)
         }
     }
+}
+
+private class GradleFacadeMessageLogger(private val log: KotlinLogger, private val warningsAsErrors: Boolean) : MessageLogger {
+    override fun report(level: FacadeLogLevel, message: String) {
+        when (level) {
+            INFO -> log.info("i: $message")
+            DEBUG -> log.debug("v: $message")
+            else -> when {
+                level == ERROR || warningsAsErrors -> log.error("e: $message")
+                else -> log.warn("w: $message")
+            }
+        }
+    }
 }
\ No newline at end of file