Support @nullable(heap) for recursive types

@nullable(heap=true) marks a parcelable field to be held in a heap
allocated wrapper like unique_ptr<T> in C++ and Box<T> in Rust.

This enables recursive parcelable types like following:

  parcelable Recursive {
    @nullable(heap=true) Recursive r;
  }

Note `r` is represented in Option<Box<Recursive>> in Rust because Box<T>
should hold a value always.

Bug: 188690695
Test: aidl_integration_test
Change-Id: Ic9b209da73c1395785c078aeecd34fda74e42e7d
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 76277fd..0cbef0b 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -98,7 +98,10 @@
 
 const std::vector<AidlAnnotation::Schema>& AidlAnnotation::AllSchemas() {
   static const std::vector<Schema> kSchemas{
-      {AidlAnnotation::Type::NULLABLE, "nullable", CONTEXT_TYPE_SPECIFIER, {}},
+      {AidlAnnotation::Type::NULLABLE,
+       "nullable",
+       CONTEXT_TYPE_SPECIFIER,
+       {{"heap", kBooleanType}}},
       {AidlAnnotation::Type::UTF8_IN_CPP, "utf8InCpp", CONTEXT_TYPE_SPECIFIER, {}},
       {AidlAnnotation::Type::SENSITIVE_DATA, "SensitiveData", CONTEXT_TYPE_INTERFACE, {}},
       {AidlAnnotation::Type::VINTF_STABILITY, "VintfStability", CONTEXT_TYPE, {}},
@@ -344,6 +347,14 @@
   return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
 }
 
+bool AidlAnnotatable::IsHeapNullable() const {
+  auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
+  if (annot) {
+    return annot->ParamValue<bool>("heap").value_or(false);
+  }
+  return false;
+}
+
 bool AidlAnnotatable::IsUtf8InCpp() const {
   return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
 }
@@ -635,6 +646,12 @@
       AIDL_ERROR(this) << "ParcelableHolder cannot be nullable.";
       return false;
     }
+    if (IsHeapNullable()) {
+      if (!defined_type || IsArray() || !defined_type->AsParcelable()) {
+        AIDL_ERROR(this) << "@nullable(heap=true) is available to parcelables.";
+        return false;
+      }
+    }
   }
   return true;
 }