Default values for fixed-size arrays

AidlConstantValue::ValueString() works with nested array values for
fixed-size arrays.

Bug: 207087196
Test: aidl_unittests
Change-Id: I420c23c791edd7578ebe76b5809be08c6b194e30
diff --git a/aidl_const_expressions.cpp b/aidl_const_expressions.cpp
index 6c4b177..14afa12 100644
--- a/aidl_const_expressions.cpp
+++ b/aidl_const_expressions.cpp
@@ -279,6 +279,11 @@
 
 bool AidlBinaryConstExpression::AreCompatibleTypes(Type t1, Type t2) {
   switch (t1) {
+    case Type::ARRAY:
+      if (t2 == Type::ARRAY) {
+        return true;
+      }
+      break;
     case Type::STRING:
       if (t2 == Type::STRING) {
         return true;
@@ -329,6 +334,12 @@
 AidlConstantValue* AidlConstantValue::Default(const AidlTypeSpecifier& specifier) {
   AidlLocation location = specifier.GetLocation();
 
+  // Initialize non-nullable fixed-size arrays with {}("empty list").
+  // Each backend will handle it differently. For example, in Rust, it can be mapped to
+  // "Default::default()".
+  if (specifier.IsFixedSizeArray() && !specifier.IsNullable()) {
+    return Array(location, std::make_unique<std::vector<std::unique_ptr<AidlConstantValue>>>());
+  }
   // allocation of int[0] is a bit wasteful in Java
   if (specifier.IsArray()) {
     return nullptr;
@@ -582,6 +593,16 @@
         err = -1;
         break;
       }
+      if (type.IsFixedSizeArray()) {
+        auto size =
+            std::get<FixedSizeArray>(type.GetArray()).dimensions.front()->EvaluatedValue<int32_t>();
+        if (values_.size() > static_cast<size_t>(size)) {
+          AIDL_ERROR(this) << "Expected an array of " << size << " elements, but found one with "
+                           << values_.size() << " elements";
+          err = -1;
+          break;
+        }
+      }
       return decorator(type, value_strings);
     }
     case Type::FLOATING: {