Remove ArrayBase

This is the only place we really make copies of types. Removing it to
make it easier to avoid copy constructors to make it easier to add
invariants to the compiler.

Bug: 201584220
Test: aidl_unittests
Change-Id: I1898e7eeed866b3b175fcecc87a395ec701f75c8
diff --git a/aidl_const_expressions.cpp b/aidl_const_expressions.cpp
index b97889d..3ec6d47 100644
--- a/aidl_const_expressions.cpp
+++ b/aidl_const_expressions.cpp
@@ -549,8 +549,11 @@
       bool success = true;
 
       for (const auto& value : values_) {
-        const AidlTypeSpecifier& array_base = type.ArrayBase();
-        const string value_string = value->ValueString(array_base, decorator);
+        string value_string;
+        type.ViewAsArrayBase([&](const AidlTypeSpecifier& base) {
+          value_string = value->ValueString(base, decorator);
+        });
+
         if (value_string.empty()) {
           success = false;
           break;
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 387941c..e694212 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -500,16 +500,14 @@
       is_array_(is_array),
       split_name_(Split(unresolved_name, ".")) {}
 
-const AidlTypeSpecifier& AidlTypeSpecifier::ArrayBase() const {
+void AidlTypeSpecifier::ViewAsArrayBase(std::function<void(const AidlTypeSpecifier&)> func) const {
   AIDL_FATAL_IF(!is_array_, this);
   // Declaring array of generic type cannot happen, it is grammar error.
   AIDL_FATAL_IF(IsGeneric(), this);
 
-  if (!array_base_) {
-    array_base_.reset(new AidlTypeSpecifier(*this));
-    array_base_->is_array_ = false;
-  }
-  return *array_base_;
+  is_array_ = false;
+  func(*this);
+  is_array_ = true;
 }
 
 string AidlTypeSpecifier::Signature() const {
@@ -1204,8 +1202,6 @@
 template <typename T>
 AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
   // Copying is not supported if it has type parameters.
-  // It doesn't make a problem because only ArrayBase() makes a copy,
-  // and it can be called only if a type is not generic.
   AIDL_FATAL_IF(other.IsGeneric(), AIDL_LOCATION_HERE);
 }
 
diff --git a/aidl_language.h b/aidl_language.h
index a920dab..205e354 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -381,8 +381,8 @@
                     vector<unique_ptr<AidlTypeSpecifier>>* type_params, const Comments& comments);
   virtual ~AidlTypeSpecifier() = default;
 
-  // Copy of this type which is not an array.
-  const AidlTypeSpecifier& ArrayBase() const;
+  // View of this type which is not an array.
+  void ViewAsArrayBase(std::function<void(const AidlTypeSpecifier&)> func) const;
 
   // Returns the full-qualified name of the base type.
   // int -> int
@@ -447,10 +447,9 @@
 
   const string unresolved_name_;
   string fully_qualified_name_;
-  bool is_array_;
+  mutable bool is_array_;
   vector<string> split_name_;
   const AidlDefinedType* defined_type_ = nullptr;  // set when Resolve() for defined types
-  mutable shared_ptr<AidlTypeSpecifier> array_base_;
 };
 
 // Returns the universal value unaltered.
diff --git a/generate_java.cpp b/generate_java.cpp
index 52c92d5..34dd5e1 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -97,7 +97,12 @@
 bool CanDescribeContents(const AidlTypeSpecifier& type, const AidlTypenames& types,
                          set<string>* describers) {
   if (type.IsArray()) {
-    if (CanDescribeContents(type.ArrayBase(), types, describers)) {
+    bool canDescribe = false;
+    type.ViewAsArrayBase([&](const AidlTypeSpecifier& base) {
+      canDescribe = CanDescribeContents(base, types, describers);
+    });
+
+    if (canDescribe) {
       describers->insert("Array");
       return true;
     }