Move SSD tree folder guards to typed Kotlin

ober

7ee9ff1952715c693f127446b31fa853b4c52a4f

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 7d90a80..640ec14 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4331,7 +4331,7 @@
                 boxTypeFallbackName boxTypeLabelMatches defaultBoxTypeLabel
                 isGenericGuessLabel isSsdPdfName
                 shouldIncludeSsdPdfChoiceName shouldIncludeSsdPdfFile
-                shouldStopSsdPdfTreeScan documentFileIsDirectory
+                shouldStopSsdPdfTreeScan documentFilePresent documentFileIsDirectory
                 documentFileIsRegular ssdPdfDocumentIsDirectory
                 ssdPdfDocumentNotDirectory
                 shouldIncludeSsdPdfDocument
@@ -4544,6 +4544,8 @@
                                        (maxDepth : Int32)) : Bool
           (or (> depth maxDepth)
               (>= currentChoices limit)))
+        (def (documentFilePresent (file : (Nullable DocumentFile))) : Bool
+          (not (nullable-null? file)))
         (def (documentFileIsDirectory (file : DocumentFile)) : Bool
           (documentFileIsDirectoryRaw file))
         (def (documentFileIsRegular (file : DocumentFile)) : Bool
@@ -9123,7 +9125,9 @@
        "    }"
        ""
        "    fun syncTree(treeUri: Uri): Pair<Int, Int> {"
-       "        val tree = DocumentFile.fromTreeUri(context, treeUri) ?: return 0 to 0"
+       "        val maybeTree = DocumentFile.fromTreeUri(context, treeUri)"
+       "        if (!documentFilePresent(maybeTree)) return 0 to 0"
+       "        val tree = checkNotNull(maybeTree)"
        "        val imported = importFromTree(tree)"
        "        if (positiveCount(imported)) invalidateTruthIndex()"
        "        rebuildLearnedExamples()"
@@ -9299,10 +9303,17 @@
        "        return count"
        "    }"
        ""
-       "    private fun ensureTreeDir(parent: DocumentFile, name: String): DocumentFile ="
-       "        parent.findFile(name.takeIf { safePathComponent(it) }"
-       "            ?: throw IllegalArgumentException(\"Unsafe tree directory\"))?.takeIf { documentFileIsDirectory(it) } ?: parent.createDirectory(name)"
-       "            ?: throw IllegalStateException(unableToCreateSyncFolderMessage(name))"
+       "    private fun ensureTreeDir(parent: DocumentFile, name: String): DocumentFile {"
+       "        if (safePathComponentInvalid(name)) throw IllegalArgumentException(\"Unsafe tree directory\")"
+       "        val existing = parent.findFile(name)"
+       "        if (documentFilePresent(existing)) {"
+       "            val existingDir = checkNotNull(existing)"
+       "            if (documentFileIsDirectory(existingDir)) return existingDir"
+       "        }"
+       "        val created = parent.createDirectory(name)"
+       "        if (!documentFilePresent(created)) throw IllegalStateException(unableToCreateSyncFolderMessage(name))"
+       "        return checkNotNull(created)"
+       "    }"
        ""
        "    private fun writeTreeFile(parent: DocumentFile, relativeName: String, source: File) {"
        "        require(safeLocalRegularFile(source))"