Emit "deprecated"

We've supported /** @deprecated note */ but it's passed to only the Java
backend as it is (as comments).

Now the deprecation is emitted properly according to the backend types.

- Java: @Deprecated + /** @deprecated note */
- C++/NDK: __attribute__((deprecated(note))
- Rust: #[deprecated = note]

For now, "note" is only available for the Java backend. Supporting
deprecation notes will be followed.

Bug: 174514415
Test: aidl_unittests / aidl_integration_test
Change-Id: Iefb216585d884b3195719c82748e573bb08922ab
Merged-In: Iefb216585d884b3195719c82748e573bb08922ab
Ignore-AOSP-First: topic with internal-only project
                  (packages/services/Car)
(cherry picked from commit ea571f8f53f30c08bc1b9a4ea02cb473522cbc9b)
diff --git a/ast_cpp.cpp b/ast_cpp.cpp
index b57527b..39af24c 100644
--- a/ast_cpp.cpp
+++ b/ast_cpp.cpp
@@ -44,15 +44,17 @@
 }
 
 ClassDecl::ClassDecl(const std::string& name, const std::string& parent,
-                     const std::vector<std::string>& template_params)
-    : name_(name), parent_(parent), template_params_(template_params) {}
+                     const std::vector<std::string>& template_params, const std::string& attributes)
+    : name_(name), parent_(parent), attributes_(attributes), template_params_(template_params) {}
 
 ClassDecl::ClassDecl(const std::string& name, const std::string& parent,
                      const std::vector<std::string>& template_params,
                      std::vector<unique_ptr<Declaration>> public_members,
-                     std::vector<unique_ptr<Declaration>> private_members)
+                     std::vector<unique_ptr<Declaration>> private_members,
+                     const std::string& attributes)
     : name_(name),
       parent_(parent),
+      attributes_(attributes),
       template_params_(template_params),
       public_members_(std::move(public_members)),
       private_members_(std::move(private_members)) {}
@@ -61,7 +63,11 @@
   if (!template_params_.empty())
     to->Write("template <typename %s>\n", base::Join(template_params_, ", typename ").c_str());
 
-  to->Write("class %s ", name_.c_str());
+  to->Write("class");
+  if (!attributes_.empty()) {
+    to->Write(" %s", attributes_.c_str());
+  }
+  to->Write(" %s ", name_.c_str());
 
   if (parent_.length() > 0) to->Write(": public %s ", parent_.c_str());
 
@@ -92,17 +98,21 @@
   private_members_.push_back(std::move(member));
 }
 
-Enum::EnumField::EnumField(const string& k, const string& v, const string& c)
-    : key(k), value(v), comment(c) {}
+Enum::EnumField::EnumField(const string& k, const string& v, const string& a)
+    : key(k), value(v), attribute(a) {}
 
-Enum::Enum(const string& name, const string& base_type, bool is_class)
-    : enum_name_(name), underlying_type_(base_type), is_class_(is_class) {}
+Enum::Enum(const string& name, const string& base_type, bool is_class,
+           const std::string& attributes)
+    : enum_name_(name), underlying_type_(base_type), attributes_(attributes), is_class_(is_class) {}
 
 void Enum::Write(CodeWriter* to) const {
   to->Write("enum ");
   if (is_class_) {
     to->Write("class ");
   }
+  if (!attributes_.empty()) {
+    to->Write("%s ", attributes_.c_str());
+  }
   if (underlying_type_.empty()) {
     to->Write("%s {\n", enum_name_.c_str());
   } else {
@@ -110,21 +120,21 @@
   }
   to->Indent();
   for (const auto& field : fields_) {
-    if (!field.comment.empty()) {
-      to->Write("%s\n", field.comment.c_str());
+    to->Write("%s", field.key.c_str());
+    if (!field.attribute.empty()) {
+      to->Write(" %s", field.attribute.c_str());
     }
-    if (field.value.empty()) {
-      to->Write("%s,\n", field.key.c_str());
-    } else {
-      to->Write("%s = %s,\n", field.key.c_str(), field.value.c_str());
+    if (!field.value.empty()) {
+      to->Write(" = %s", field.value.c_str());
     }
+    to->Write(",\n");
   }
   to->Dedent();
   to->Write("};\n");
 }
 
-void Enum::AddValue(const string& key, const string& value, const string& comment) {
-  fields_.emplace_back(key, value, comment);
+void Enum::AddValue(const string& key, const string& value, const string& attribute) {
+  fields_.emplace_back(key, value, attribute);
 }
 
 ArgList::ArgList(const std::string& single_argument)
@@ -192,15 +202,15 @@
   to->Write("\n");
 }
 
-MethodDecl::MethodDecl(const std::string& return_type,
-                       const std::string& name,
-                       ArgList&& arg_list)
-    : MethodDecl(return_type, name, std::move(arg_list), 0u) {}
+MethodDecl::MethodDecl(const std::string& return_type, const std::string& name, ArgList&& arg_list,
+                       const std::string& attributes)
+    : MethodDecl(return_type, name, std::move(arg_list), 0u, attributes) {}
 
 MethodDecl::MethodDecl(const std::string& return_type, const std::string& name, ArgList&& arg_list,
-                       uint32_t modifiers)
+                       uint32_t modifiers, const std::string& attributes)
     : return_type_(return_type),
       name_(name),
+      attributes_(attributes),
       arguments_(std::move(arg_list)),
       is_const_(modifiers & IS_CONST),
       is_virtual_(modifiers & IS_VIRTUAL),
@@ -228,6 +238,8 @@
 
   if (is_final_) to->Write(" final");
 
+  if (!attributes_.empty()) to->Write(" %s", attributes_.c_str());
+
   if (is_pure_virtual_)
     to->Write(" = 0");