Add implementation of primitive text types

Bug: 297575681
Test: unbaselined test
Change-Id: Id4ce821d1dc508645bb0e9c5d39b4cb5c6f7b6a9
diff --git a/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt b/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt
index d106b54..b41b53f 100644
--- a/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt
+++ b/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeItem.kt
@@ -22,6 +22,7 @@
 import com.android.tools.metalava.model.JAVA_LANG_PREFIX
 import com.android.tools.metalava.model.MemberItem
 import com.android.tools.metalava.model.MethodItem
+import com.android.tools.metalava.model.PrimitiveTypeItem
 import com.android.tools.metalava.model.TypeItem
 import com.android.tools.metalava.model.TypeParameterItem
 import com.android.tools.metalava.model.TypeParameterList
@@ -31,7 +32,8 @@
 
 const val ASSUME_TYPE_VARS_EXTEND_OBJECT = false
 
-class TextTypeItem(val codebase: TextCodebase, val type: String) : TypeItem {
+// TODO: change from `open` to `sealed` once parsing is done and only the implementations are used
+open class TextTypeItem(open val codebase: TextCodebase, open val type: String) : TypeItem {
 
     override fun toString(): String = type
 
@@ -417,3 +419,10 @@
         }
     }
 }
+
+/** A [PrimitiveTypeItem] parsed from a signature file. */
+internal class TextPrimitiveTypeItem(
+    override val codebase: TextCodebase,
+    override val type: String,
+    override val kind: PrimitiveTypeItem.Primitive
+) : PrimitiveTypeItem, TextTypeItem(codebase, type)
diff --git a/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeParser.kt b/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeParser.kt
index e9c65d1..31c8fa7 100644
--- a/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeParser.kt
+++ b/metalava-model-text/src/main/java/com/android/tools/metalava/model/text/TextTypeParser.kt
@@ -16,6 +16,7 @@
 
 package com.android.tools.metalava.model.text
 
+import com.android.tools.metalava.model.PrimitiveTypeItem
 import com.android.tools.metalava.model.TypeParameterItem
 import java.util.HashMap
 import kotlin.math.min
@@ -51,6 +52,17 @@
 
     /** Converts the [type] to a [TextTypeItem] in the context of the [typeParams]. */
     private fun parseType(type: String, typeParams: List<TypeParameterItem>): TextTypeItem {
+        // TODO(b/300081840): handle annotations
+        val (unannotated, _) = trimLeadingAnnotations(type)
+        val (withoutNullability, _) = splitNullabilitySuffix(unannotated)
+        val trimmed = withoutNullability.trim()
+
+        // Figure out what kind of type this is. Start with the simple case: primitive.
+        return asPrimitive(type, trimmed) ?: parseUnknownType(type, typeParams)
+    }
+
+    /** Temporary method for parsing an unknown kind of type, until [parseType] is complete. */
+    private fun parseUnknownType(type: String, typeParams: List<TypeParameterItem>): TextTypeItem {
         if (typeParams.isNotEmpty() && TextTypeItem.isLikelyTypeParameter(type)) {
             // Find the "name" part of the type (before a list of type parameters, array marking,
             // or nullability annotation), and see if it is a type parameter name.
@@ -116,6 +128,31 @@
             !isPrimitive(s.substring(0, typeEnd).trim())
     }
 
+    /**
+     * Try parsing [type] as a primitive. This will return a non-null [TextPrimitiveTypeItem] if
+     * [type] exactly matches a primitive name.
+     *
+     * [type] should have annotations and nullability markers stripped, with [original] as the
+     * complete annotated type. Once annotations are properly handled (b/300081840), preserving
+     * [original] won't be necessary.
+     */
+    private fun asPrimitive(original: String, type: String): TextPrimitiveTypeItem? {
+        val kind =
+            when (type) {
+                "byte" -> PrimitiveTypeItem.Primitive.BYTE
+                "char" -> PrimitiveTypeItem.Primitive.CHAR
+                "double" -> PrimitiveTypeItem.Primitive.DOUBLE
+                "float" -> PrimitiveTypeItem.Primitive.FLOAT
+                "int" -> PrimitiveTypeItem.Primitive.INT
+                "long" -> PrimitiveTypeItem.Primitive.LONG
+                "short" -> PrimitiveTypeItem.Primitive.SHORT
+                "boolean" -> PrimitiveTypeItem.Primitive.BOOLEAN
+                "void" -> PrimitiveTypeItem.Primitive.VOID
+                else -> return null
+            }
+        return TextPrimitiveTypeItem(codebase, original, kind)
+    }
+
     private class Cache<Key, Value> {
         private val cache = HashMap<Key, Value>()
 
diff --git a/metalava-model-text/src/test/resources/model-test-suite-baseline.txt b/metalava-model-text/src/test/resources/model-test-suite-baseline.txt
index 720ee03..68a27cb 100644
--- a/metalava-model-text/src/test/resources/model-test-suite-baseline.txt
+++ b/metalava-model-text/src/test/resources/model-test-suite-baseline.txt
@@ -4,7 +4,6 @@
   Test inner types[text,signature]
   Test multidimensional primitive array types[text,signature]
   Test primitive array types[text,signature]
-  Test primitive types[text,signature]
   Test primitive vararg types[text,signature]
   Test variable types[text,signature]
   Test wildcard types[text,signature]