union: java backend

union is a parcelable which can hold only a single field with a tag.

Example:
  union Union {
    int n;
    String s;
  }

In Java, you can instantiate it with
- default constructor: init with first field
- value constructor: Union.n(42) or Union.s("abc")

You can query "tag" before getting the contents from it.
It also supports getter/setter.

Example:
  void foo(Union u) {
    if (u.getTag() == Union.n) {  // query
      int n = u.getN();           // getter
      ...
    }
    u.setS("abc");                // setter
  }

Bug: 150948558
Test: atest aidl_integration_test
Change-Id: I5c2d87e09462c0d3c6617d73fdf0e49c281d551e
diff --git a/aidl_checkapi.cpp b/aidl_checkapi.cpp
index 0f2f4b0..f20b5ca 100644
--- a/aidl_checkapi.cpp
+++ b/aidl_checkapi.cpp
@@ -182,8 +182,8 @@
   return specifier.IsNullable();
 }
 
-static bool are_compatible_parcelables(const AidlStructuredParcelable& older,
-                                       const AidlStructuredParcelable& newer) {
+template <typename ParcelableType>
+static bool are_compatible_parcelables(const ParcelableType& older, const ParcelableType& newer) {
   const auto& old_fields = older.GetFields();
   const auto& new_fields = newer.GetFields();
   if (old_fields.size() > new_fields.size()) {
@@ -370,6 +370,16 @@
       }
       compatible &= are_compatible_parcelables(*(old_type->AsStructuredParcelable()),
                                                *(new_type->AsStructuredParcelable()));
+    } else if (old_type->AsUnionDeclaration() != nullptr) {
+      if (new_type->AsUnionDeclaration() == nullptr) {
+        AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
+                             << " is changed from " << old_type->GetPreprocessDeclarationName()
+                             << " to " << new_type->GetPreprocessDeclarationName();
+        compatible = false;
+        continue;
+      }
+      compatible &= are_compatible_parcelables(*(old_type->AsUnionDeclaration()),
+                                               *(new_type->AsUnionDeclaration()));
     } else if (old_type->AsEnumDeclaration() != nullptr) {
       if (new_type->AsEnumDeclaration() == nullptr) {
         AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()