Preserve "@hide" comment during dump_api

For now, remove every comment during dumping API, but it makes dump_api
preserve "@hide"

In addition, make constant value support comments.

And also, ran freeze-api with and without @hide to check if comments
don't break during 'check-api'

Bug: 139920660
Test: m
Test: ./runtests.sh
Change-Id: I7b3050161af5edfd93821628bbdb410ce0c2df51
diff --git a/aidl.cpp b/aidl.cpp
index 1fcff6d..083d520 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -842,7 +842,7 @@
         if (!type->GetPackage().empty()) {
           (*writer) << "package " << type->GetPackage() << ";\n";
         }
-        type->Write(writer.get());
+        type->Dump(writer.get());
       }
     } else {
       return false;
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 6cb056f..c591c45 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -55,7 +55,7 @@
 using std::vector;
 
 namespace {
-bool is_java_keyword(const char* str) {
+bool IsJavaKeyword(const char* str) {
   static const std::vector<std::string> kJavaKeywords{
       "abstract", "assert", "boolean",    "break",     "byte",       "case",      "catch",
       "char",     "class",  "const",      "continue",  "default",    "do",        "double",
@@ -68,6 +68,14 @@
   };
   return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end();
 }
+
+void AddHideComment(CodeWriter* writer) {
+  writer->Write("/* @hide */\n");
+}
+
+inline bool HasHideComment(const std::string& comment) {
+  return std::regex_search(comment, std::regex("@hide\\b"));
+}
 }  // namespace
 
 void yylex_init(void **);
@@ -340,6 +348,10 @@
   return array_base;
 }
 
+bool AidlTypeSpecifier::IsHidden() const {
+  return HasHideComment(GetComments());
+}
+
 string AidlTypeSpecifier::ToString() const {
   string ret = GetName();
   if (IsGeneric()) {
@@ -620,6 +632,9 @@
   }
 }
 
+bool AidlMethod::IsHidden() const {
+  return HasHideComment(GetComments());
+}
 
 string AidlMethod::Signature() const {
   vector<string> arg_signatures;
@@ -651,6 +666,10 @@
   return Join(package_, '.');
 }
 
+bool AidlDefinedType::IsHidden() const {
+  return HasHideComment(GetComments());
+}
+
 std::string AidlDefinedType::GetCanonicalName() const {
   if (package_.empty()) {
     return GetName();
@@ -720,7 +739,7 @@
   return true;
 }
 
-void AidlParcelable::Write(CodeWriter* writer) const {
+void AidlParcelable::Dump(CodeWriter* writer) const {
   writer->Write("parcelable %s ;\n", GetName().c_str());
 }
 
@@ -730,10 +749,16 @@
     : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
       variables_(std::move(*variables)) {}
 
-void AidlStructuredParcelable::Write(CodeWriter* writer) const {
+void AidlStructuredParcelable::Dump(CodeWriter* writer) const {
+  if (this->IsHidden()) {
+    AddHideComment(writer);
+  }
   writer->Write("parcelable %s {\n", GetName().c_str());
   writer->Indent();
   for (const auto& field : GetFields()) {
+    if (field->GetType().IsHidden()) {
+      AddHideComment(writer);
+    }
     writer->Write("%s;\n", field->ToString().c_str());
   }
   writer->Dedent();
@@ -901,7 +926,7 @@
   return success;
 }
 
-void AidlEnumDeclaration::Write(CodeWriter* writer) const {
+void AidlEnumDeclaration::Dump(CodeWriter* writer) const {
   writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
   writer->Write("enum %s {\n", GetName().c_str());
   writer->Indent();
@@ -953,13 +978,22 @@
   delete members;
 }
 
-void AidlInterface::Write(CodeWriter* writer) const {
+void AidlInterface::Dump(CodeWriter* writer) const {
+  if (this->IsHidden()) {
+    AddHideComment(writer);
+  }
   writer->Write("interface %s {\n", GetName().c_str());
   writer->Indent();
   for (const auto& method : GetMethods()) {
+    if (method->IsHidden()) {
+      AddHideComment(writer);
+    }
     writer->Write("%s;\n", method->ToString().c_str());
   }
   for (const auto& constdecl : GetConstantDeclarations()) {
+    if (constdecl->GetType().IsHidden()) {
+      AddHideComment(writer);
+    }
     writer->Write("%s;\n", constdecl->ToString().c_str());
   }
   writer->Dedent();
@@ -1013,7 +1047,7 @@
       }
 
       // check that the name doesn't match a keyword
-      if (is_java_keyword(arg->GetName().c_str())) {
+      if (IsJavaKeyword(arg->GetName().c_str())) {
         AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
         return false;
       }
diff --git a/aidl_language.h b/aidl_language.h
index d35d3e2..b8ee857 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -22,6 +22,7 @@
 #include "options.h"
 
 #include <memory>
+#include <regex>
 #include <string>
 #include <unordered_set>
 #include <vector>
@@ -290,6 +291,8 @@
 
   const string& GetUnresolvedName() const { return unresolved_name_; }
 
+  bool IsHidden() const;
+
   const string& GetComments() const { return comments_; }
 
   const std::vector<std::string> GetSplitName() const { return split_name_; }
@@ -548,7 +551,7 @@
   virtual ~AidlMethod() = default;
 
   AidlMethod* AsMethod() override { return this; }
-
+  bool IsHidden() const;
   const string& GetComments() const { return comments_; }
   const AidlTypeSpecifier& GetType() const { return *type_; }
   AidlTypeSpecifier* GetMutableType() { return type_.get(); }
@@ -637,6 +640,7 @@
   virtual ~AidlDefinedType() = default;
 
   const std::string& GetName() const { return name_; };
+  bool IsHidden() const;
   const std::string& GetComments() const { return comments_; }
   void SetComments(const std::string comments) { comments_ = comments; }
 
@@ -684,7 +688,7 @@
         const_cast<const AidlDefinedType*>(this)->AsUnstructuredParcelable());
   }
 
-  virtual void Write(CodeWriter* writer) const = 0;
+  virtual void Dump(CodeWriter* writer) const = 0;
 
  private:
   std::string name_;
@@ -713,7 +717,7 @@
   const AidlNode& AsAidlNode() const override { return *this; }
   std::string GetPreprocessDeclarationName() const override { return "parcelable"; }
 
-  void Write(CodeWriter* writer) const override;
+  void Dump(CodeWriter* writer) const override;
 
  private:
   std::unique_ptr<AidlQualifiedName> name_;
@@ -735,7 +739,7 @@
   const AidlStructuredParcelable* AsStructuredParcelable() const override { return this; }
   std::string GetPreprocessDeclarationName() const override { return "structured_parcelable"; }
 
-  void Write(CodeWriter* writer) const override;
+  void Dump(CodeWriter* writer) const override;
 
   bool CheckValid(const AidlTypenames& typenames) const override;
   bool LanguageSpecificCheckValid(Options::Language lang) const override;
@@ -786,7 +790,7 @@
   bool CheckValid(const AidlTypenames& typenames) const override;
   bool LanguageSpecificCheckValid(Options::Language) const override { return true; }
   std::string GetPreprocessDeclarationName() const override { return "enum"; }
-  void Write(CodeWriter*) const override;
+  void Dump(CodeWriter* writer) const override;
 
   const AidlEnumDeclaration* AsEnumDeclaration() const override { return this; }
 
@@ -815,7 +819,7 @@
   const AidlInterface* AsInterface() const override { return this; }
   std::string GetPreprocessDeclarationName() const override { return "interface"; }
 
-  void Write(CodeWriter* writer) const override;
+  void Dump(CodeWriter* writer) const override;
 
   bool CheckValid(const AidlTypenames& typenames) const override;
   bool LanguageSpecificCheckValid(Options::Language lang) const override;
diff --git a/aidl_language_l.ll b/aidl_language_l.ll
index 25a3465..4813da6 100644
--- a/aidl_language_l.ll
+++ b/aidl_language_l.ll
@@ -110,7 +110,8 @@
 out                   { return yy::parser::token::OUT; }
 inout                 { return yy::parser::token::INOUT; }
 cpp_header            { return yy::parser::token::CPP_HEADER; }
-const                 { return yy::parser::token::CONST; }
+const                 { yylval->token = new AidlToken("const", extra_text);
+                        return yy::parser::token::CONST; }
 true                  { return yy::parser::token::TRUE_LITERAL; }
 false                 { return yy::parser::token::FALSE_LITERAL; }
 
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index 2d367d3..2cbbfa8 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -107,6 +107,7 @@
 %token<token> PARCELABLE "parcelable"
 %token<token> ONEWAY "oneway"
 %token<token> ENUM "enum"
+%token<token> CONST "const"
 
 %token<character> CHARVALUE "char literal"
 %token<token> FLOATVALUE "float literal"
@@ -114,7 +115,6 @@
 %token<token> INTVALUE "int literal"
 
 %token '(' ')' ',' '=' '[' ']' '.' '{' '}' ';'
-%token CONST "const"
 %token UNKNOWN "unrecognized character"
 %token CPP_HEADER "cpp_header"
 %token IMPORT "import"
@@ -488,6 +488,7 @@
 
 constant_decl
  : CONST type identifier '=' const_expr ';' {
+    $2->SetComments($1->GetComments());
     $$ = new AidlConstantDeclaration(loc(@3), $2, $3->GetText(), $5);
     delete $3;
    }
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 4521b65..58e391e 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -833,24 +833,31 @@
       "foo/bar/IFoo.aidl",
       "package foo.bar;\n"
       "import foo.bar.Data;\n"
-      "// comment\n"
+      "// comment @hide\n"
       "interface IFoo {\n"
+      "    /* @hide */\n"
       "    int foo(out int[] a, String b, boolean c, inout List<String>  d);\n"
       "    int foo2(@utf8InCpp String x, inout List<String>  y);\n"
       "    IFoo foo3(IFoo foo);\n"
       "    Data getData();\n"
+      "    // @hide\n"
       "    const int A = 1;\n"
       "    const String STR = \"Hello\";\n"
       "}\n");
   io_delegate_.SetFileContents("foo/bar/Data.aidl",
                                "package foo.bar;\n"
                                "import foo.bar.IFoo;\n"
+                               "/* @hide*/\n"
                                "parcelable Data {\n"
+                               "   // @hide\n"
                                "   int x = 10;\n"
+                               "   // @hide\n"
                                "   int y;\n"
                                "   IFoo foo;\n"
                                "   List<IFoo> a;\n"
+                               "   /*@hide2*/\n"
                                "   List<foo.bar.IFoo> b;\n"
+                               "   // It should be @hide property\n"
                                "   @nullable String[] c;\n"
                                "}\n");
   io_delegate_.SetFileContents("api.aidl", "");
@@ -862,11 +869,14 @@
   string actual;
   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
   EXPECT_EQ(actual, R"(package foo.bar;
+/* @hide */
 interface IFoo {
+  /* @hide */
   int foo(out int[] a, String b, boolean c, inout List<String> d);
   int foo2(@utf8InCpp String x, inout List<String> y);
   foo.bar.IFoo foo3(foo.bar.IFoo foo);
   foo.bar.Data getData();
+  /* @hide */
   const int A = 1;
   const String STR = "Hello";
 }
@@ -874,12 +884,16 @@
 
   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
   EXPECT_EQ(actual, R"(package foo.bar;
+/* @hide */
 parcelable Data {
+  /* @hide */
   int x = 10;
+  /* @hide */
   int y;
   foo.bar.IFoo foo;
   List<foo.bar.IFoo> a;
   List<foo.bar.IFoo> b;
+  /* @hide */
   @nullable String[] c;
 }
 )");
diff --git a/build/Android.bp b/build/Android.bp
index c7d569f..32ca73a 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -82,7 +82,11 @@
         "tests_1/some_package/Thing.aidl",
         "tests_1/some_package/sub_package/*.aidl", // testing glob w/o filegroup
     ],
-    versions: ["1"],
+    versions: [
+        "1",
+        "2",
+        "3",
+    ],
 }
 
 aidl_interface {
@@ -130,5 +134,8 @@
     imports: [
         "test-piece-2",
     ],
-    versions: ["1", "2"],
+    versions: [
+        "1",
+        "2",
+    ],
 }
diff --git a/build/aidl_api/test-piece-1/2/.hash b/build/aidl_api/test-piece-1/2/.hash
new file mode 100644
index 0000000..c28f432
--- /dev/null
+++ b/build/aidl_api/test-piece-1/2/.hash
@@ -0,0 +1 @@
+09c794283cac3ff37406d1e5593f8a4f4940562f  -
diff --git a/build/aidl_api/test-piece-1/2/some_package/IFoo.aidl b/build/aidl_api/test-piece-1/2/some_package/IFoo.aidl
new file mode 100644
index 0000000..e50ee27
--- /dev/null
+++ b/build/aidl_api/test-piece-1/2/some_package/IFoo.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package;
+interface IFoo {
+  /* @hide */
+  void CanYouDealWithThisThing(inout some_package.Thing parcel);
+  /* @hide */
+  void CanYouDealWithThisSubThing(inout some_package.sub_package.SubThing parcel);
+}
diff --git a/build/aidl_api/test-piece-1/2/some_package/Thing.aidl b/build/aidl_api/test-piece-1/2/some_package/Thing.aidl
new file mode 100644
index 0000000..3a30cc5
--- /dev/null
+++ b/build/aidl_api/test-piece-1/2/some_package/Thing.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package;
+parcelable Thing {
+  int a;
+  int b;
+}
diff --git a/build/aidl_api/test-piece-1/2/some_package/sub_package/IFoo.aidl b/build/aidl_api/test-piece-1/2/some_package/sub_package/IFoo.aidl
new file mode 100644
index 0000000..f45996d
--- /dev/null
+++ b/build/aidl_api/test-piece-1/2/some_package/sub_package/IFoo.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package.sub_package;
+interface IFoo {
+  void CanYouDealWithThisThing(inout some_package.Thing parcel);
+  void CanYouDealWithThisSubThing(inout some_package.sub_package.SubThing parcel);
+}
diff --git a/build/aidl_api/test-piece-1/2/some_package/sub_package/SubThing.aidl b/build/aidl_api/test-piece-1/2/some_package/sub_package/SubThing.aidl
new file mode 100644
index 0000000..adad68f
--- /dev/null
+++ b/build/aidl_api/test-piece-1/2/some_package/sub_package/SubThing.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package.sub_package;
+parcelable SubThing {
+  int a;
+  int b;
+}
diff --git a/build/aidl_api/test-piece-1/3/.hash b/build/aidl_api/test-piece-1/3/.hash
new file mode 100644
index 0000000..24d0448
--- /dev/null
+++ b/build/aidl_api/test-piece-1/3/.hash
@@ -0,0 +1 @@
+09b8aace9633aa35010b28a424d647dfcb4db5ea  -
diff --git a/build/aidl_api/test-piece-1/3/some_package/IFoo.aidl b/build/aidl_api/test-piece-1/3/some_package/IFoo.aidl
new file mode 100644
index 0000000..686805c
--- /dev/null
+++ b/build/aidl_api/test-piece-1/3/some_package/IFoo.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package;
+interface IFoo {
+  void CanYouDealWithThisThing(inout some_package.Thing parcel);
+  void CanYouDealWithThisSubThing(inout some_package.sub_package.SubThing parcel);
+}
diff --git a/build/aidl_api/test-piece-1/3/some_package/Thing.aidl b/build/aidl_api/test-piece-1/3/some_package/Thing.aidl
new file mode 100644
index 0000000..3a30cc5
--- /dev/null
+++ b/build/aidl_api/test-piece-1/3/some_package/Thing.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package;
+parcelable Thing {
+  int a;
+  int b;
+}
diff --git a/build/aidl_api/test-piece-1/3/some_package/sub_package/IFoo.aidl b/build/aidl_api/test-piece-1/3/some_package/sub_package/IFoo.aidl
new file mode 100644
index 0000000..f45996d
--- /dev/null
+++ b/build/aidl_api/test-piece-1/3/some_package/sub_package/IFoo.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package.sub_package;
+interface IFoo {
+  void CanYouDealWithThisThing(inout some_package.Thing parcel);
+  void CanYouDealWithThisSubThing(inout some_package.sub_package.SubThing parcel);
+}
diff --git a/build/aidl_api/test-piece-1/3/some_package/sub_package/SubThing.aidl b/build/aidl_api/test-piece-1/3/some_package/sub_package/SubThing.aidl
new file mode 100644
index 0000000..adad68f
--- /dev/null
+++ b/build/aidl_api/test-piece-1/3/some_package/sub_package/SubThing.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package some_package.sub_package;
+parcelable SubThing {
+  int a;
+  int b;
+}
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 1e27188..296e023 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -1083,7 +1083,11 @@
   // all the declared constants of the interface
   for (const auto& constant : iface->GetConstantDeclarations()) {
     const AidlConstantValue& value = constant->GetValue();
-
+    auto comment = constant->GetType().GetComments();
+    if (comment.length() != 0) {
+      auto code = StringPrintf("%s\n", comment.c_str());
+      interface->elements.push_back(std::make_shared<LiteralClassElement>(code));
+    }
     switch (value.GetType()) {
       case AidlConstantValue::Type::STRING: {
         generate_string_constant(interface.get(), constant->GetName(),