Put data in AidlMethod behind getters and setters

Change-Id: I453ab9bcbbc610df4109d691283e7b872e0078a4
Test: Unit tests
Bug: 24410295
Signed-off-by: Casey Dahlin <sadmac@google.com>
diff --git a/aidl.cpp b/aidl.cpp
index b63c869..f596b93 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -204,28 +204,31 @@
                 interface_type* c,
                 TypeNamespace* types) {
   int err = 0;
-  set<string> method_names;
+
+  // Has to be a pointer due to deleting copy constructor. No idea why.
+  map<string, const AidlMethod*> method_names;
   for (const auto& m : *c->methods) {
-    if (!types->AddContainerType(m->type->GetName()) ||
-        !types->IsValidReturnType(*m->type, filename)) {
+    if (!types->AddContainerType(m->GetType().GetName()) ||
+        !types->IsValidReturnType(m->GetType(), filename)) {
       err = 1;  // return type is invalid
     }
 
     int index = 1;
-    for (const auto& arg : *m->args) {
+    for (const auto& arg : m->GetArguments()) {
       if (!types->AddContainerType(arg->GetType().GetName()) ||
           !types->IsValidArg(*arg, index, filename)) {
         err = 1;
       }
     }
 
+    auto it = method_names.find(m->GetName());
     // prevent duplicate methods
-    if (method_names.find(m->name.data) == method_names.end()) {
-      method_names.insert(m->name.data);
+    if (it == method_names.end()) {
+      method_names[m->GetName()] = m.get();
     } else {
-      cerr << filename << ":" << m->name.lineno
-           << " attempt to redefine method " << m->name.data << "," << endl
-           << filename << ":" << m->name.lineno
+      cerr << filename << ":" << m->GetLine()
+           << " attempt to redefine method " << m->GetName() << "," << endl
+           << filename << ":" << it->second->GetLine()
            << "    previously defined here." << endl;
       err = 1;
     }
@@ -457,29 +460,28 @@
     bool hasUnassignedIds = false;
     bool hasAssignedIds = false;
     for (const auto& item : items) {
-        if (item->hasId) {
+        if (item->HasId()) {
             hasAssignedIds = true;
-            item->assigned_id = atoi(item->id.data);
             // Ensure that the user set id is not duplicated.
-            if (usedIds.find(item->assigned_id) != usedIds.end()) {
+            if (usedIds.find(item->GetId()) != usedIds.end()) {
                 // We found a duplicate id, so throw an error.
                 fprintf(stderr,
                         "%s:%d Found duplicate method id (%d) for method: %s\n",
-                        filename, item->id.lineno,
-                        item->assigned_id, item->name.data);
+                        filename, item->GetLine(),
+                        item->GetId(), item->GetName().c_str());
                 return 1;
             }
             // Ensure that the user set id is within the appropriate limits
-            if (item->assigned_id < kMinUserSetMethodId ||
-                    item->assigned_id > kMaxUserSetMethodId) {
+            if (item->GetId() < kMinUserSetMethodId ||
+                    item->GetId() > kMaxUserSetMethodId) {
                 fprintf(stderr, "%s:%d Found out of bounds id (%d) for method: %s\n",
-                        filename, item->id.lineno,
-                        item->assigned_id, item->name.data);
+                        filename, item->GetLine(),
+                        item->GetId(), item->GetName().c_str());
                 fprintf(stderr, "    Value for id must be between %d and %d inclusive.\n",
                         kMinUserSetMethodId, kMaxUserSetMethodId);
                 return 1;
             }
-            usedIds.insert(item->assigned_id);
+            usedIds.insert(item->GetId());
         } else {
             hasUnassignedIds = true;
         }
@@ -495,7 +497,7 @@
     if (hasUnassignedIds) {
         int newId = 0;
         for (const auto& item : items) {
-            item->assigned_id = newId++;
+            item->SetId(newId++);
         }
     }
 
diff --git a/aidl_language.cpp b/aidl_language.cpp
index ab87107..21a32ad 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -106,8 +106,26 @@
   return ret;
 }
 
-AidlMethod::AidlMethod(std::string comments)
-    : comments_(comments) {}
+AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
+                       std::vector<std::unique_ptr<AidlArgument>>* args,
+                       unsigned line, std::string comments, int id)
+    : oneway_(oneway),
+      comments_(comments),
+      type_(type),
+      name_(name),
+      line_(line),
+      arguments_(std::move(*args)),
+      id_(id) {
+  has_id_ = true;
+  delete args;
+}
+
+AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
+                       std::vector<std::unique_ptr<AidlArgument>>* args,
+                       unsigned line, std::string comments)
+    : AidlMethod(oneway, type, name, args, line, comments, 0) {
+  has_id_ = false;
+}
 
 string Parser::FileName() {
   return filename_;
@@ -188,4 +206,3 @@
 {
   return imports_;
 }
-
diff --git a/aidl_language.h b/aidl_language.h
index c870111..5303d7b 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -100,23 +100,36 @@
 
 class AidlMethod {
  public:
-  AidlMethod(std::string comments);
+  AidlMethod(bool oneway, AidlType* type, std::string name,
+             std::vector<std::unique_ptr<AidlArgument>>* args,
+             unsigned line, std::string comments);
+  AidlMethod(bool oneway, AidlType* type, std::string name,
+             std::vector<std::unique_ptr<AidlArgument>>* args,
+             unsigned line, std::string comments, int id);
   virtual ~AidlMethod() = default;
 
-  std::string GetComments() const { return comments_; }
+  const std::string& GetComments() const { return comments_; }
+  const AidlType& GetType() const { return *type_; }
+  bool IsOneway() const { return oneway_; }
+  const std::string& GetName() const { return name_; }
+  unsigned GetLine() const { return line_; }
+  bool HasId() const { return has_id_; }
+  int GetId() { return id_; }
+  void SetId(unsigned id) { id_ = id; }
 
-  AidlType* type;
-  bool oneway;
-  buffer_type oneway_token;
-  buffer_type name;
-  std::vector<std::unique_ptr<AidlArgument>>* args;
-  bool hasId;
-  buffer_type id;
-  buffer_type semicolon_token;
-  int assigned_id;
+  const std::vector<std::unique_ptr<AidlArgument>>& GetArguments() const {
+      return arguments_;
+  }
 
  private:
+  bool oneway_;
   std::string comments_;
+  std::unique_ptr<AidlType> type_;
+  std::string name_;
+  unsigned line_;
+  std::vector<std::unique_ptr<AidlArgument>> arguments_;
+  bool has_id_;
+  int id_;
 
   DISALLOW_COPY_AND_ASSIGN(AidlMethod);
 };
diff --git a/aidl_language_l.l b/aidl_language_l.l
index d6508db..dc2f80c 100644
--- a/aidl_language_l.l
+++ b/aidl_language_l.l
@@ -87,9 +87,9 @@
 ;               { SET_BUFFER(';'); return ';'; }
 \{              { SET_BUFFER('{'); return '{'; }
 \}              { SET_BUFFER('}'); return '}'; }
-,               { SET_BUFFER(','); return ','; }
-=               { SET_BUFFER('='); return '='; }
 
+=               { return '='; }
+,               { return ','; }
 \(              { return '('; }
 \)              { return ')'; }
 
diff --git a/aidl_language_y.y b/aidl_language_y.y
index 28c86c2..82576ab 100644
--- a/aidl_language_y.y
+++ b/aidl_language_y.y
@@ -36,8 +36,8 @@
 }
 
 %token<buffer> IMPORT PACKAGE IDENTIFIER IDVALUE GENERIC ARRAY PARCELABLE
-%token<buffer> ONEWAY INTERFACE ';' '{' '}' ',' '='
-%token IN OUT INOUT '(' ')'
+%token<buffer> ONEWAY INTERFACE ';' '{' '}'
+%token IN OUT INOUT '(' ')' ',' '='
 
 %type<document_item> document_items declaration
 %type<user_data> parcelable_decl
@@ -187,58 +187,24 @@
     $$ = $1;
   };
 
-method_decl:
-        type IDENTIFIER '(' arg_list ')' ';'  {
-                                                        AidlMethod *method = new AidlMethod($1->GetComments());
-                                                        method->oneway = false;
-                                                        method->type = $1;
-                                                        memset(&method->oneway_token, 0, sizeof(buffer_type));
-                                                        method->name = $2;
-                                                        method->args = $4;
-                                                        method->hasId = false;
-                                                        memset(&method->id, 0, sizeof(buffer_type));
-                                                        method->semicolon_token = $6;
-                                                        $$ = method;
-                                                    }
-    |   ONEWAY type IDENTIFIER '(' arg_list ')' ';'  {
-                                                        AidlMethod *method =
-                                                            new AidlMethod(android::aidl::gather_comments($1.extra));
-                                                        method->oneway = true;
-                                                        method->oneway_token = $1;
-                                                        method->type = $2;
-                                                        method->name = $3;
-                                                        method->args = $5;
-                                                        method->hasId = false;
-                                                        memset(&method->id, 0, sizeof(buffer_type));
-                                                        method->semicolon_token = $7;
-                                                        $$ = method;
-                                                    }
-    |    type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';'  {
-                                                        AidlMethod *method = new AidlMethod($1->GetComments());
-                                                        method->oneway = false;
-                                                        memset(&method->oneway_token, 0, sizeof(buffer_type));
-                                                        method->type = $1;
-                                                        method->name = $2;
-                                                        method->args = $4;
-                                                        method->hasId = true;
-                                                        method->id = $7;
-                                                        method->semicolon_token = $8;
-                                                        $$ = method;
-                                                    }
-    |   ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';'  {
-                                                        AidlMethod *method =
-                                                            new AidlMethod(android::aidl::gather_comments($1.extra));
-                                                        method->oneway = true;
-                                                        method->oneway_token = $1;
-                                                        method->type = $2;
-                                                        method->name = $3;
-                                                        method->args = $5;
-                                                        method->hasId = true;
-                                                        method->id = $8;
-                                                        method->semicolon_token = $9;
-                                                        $$ = method;
-                                                    }
-    ;
+method_decl
+ : type IDENTIFIER '(' arg_list ')' ';' {
+    $$ = new AidlMethod(false, $1, $2.Literal(), $4, @2.begin.line,
+                        $1->GetComments());
+  }
+ | ONEWAY type IDENTIFIER '(' arg_list ')' ';' {
+    $$ = new AidlMethod(true, $2, $3.Literal(), $5, @3.begin.line,
+                        android::aidl::gather_comments($1.extra));
+  }
+ | type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
+    $$ = new AidlMethod(false, $1, $2.Literal(), $4, @2.begin.line,
+                        $1->GetComments(), std::stoi($7.data));
+  }
+ | ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
+    $$ = new AidlMethod(true, $2, $3.Literal(), $5, @3.begin.line,
+                        android::aidl::gather_comments($1.extra),
+                        std::stoi($8.data));
+  };
 
 arg_list
  :
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 0df7ae9..c86fa79 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -69,13 +69,13 @@
                                         const TypeNamespace& types,
                                         bool for_interface) {
   vector<string> args;
-  for (const unique_ptr<AidlArgument>& arg : *method.args) {
+  for (const unique_ptr<AidlArgument>& arg : method.GetArguments()) {
     args.push_back(GetCPPVarDec(
           types, arg->GetType(), arg->GetName(),
           AidlArgument::OUT_DIR & arg->GetDirection()));
   }
 
-  string return_arg = GetCPPVarDec(types, *method.type, "_aidl_return", true);
+  string return_arg = GetCPPVarDec(types, method.GetType(), "_aidl_return", true);
   args.push_back(return_arg);
 
   uint32_t modifiers = 0;
@@ -88,7 +88,7 @@
 
   return unique_ptr<Declaration>{
       new MethodDecl{kAndroidStatusLiteral,
-                     method.name.Literal(),
+                     method.GetName(),
                      args,
                      modifiers}};
 }
@@ -235,9 +235,9 @@
   for (const auto& method : *parsed_doc.methods) {
     if_class->AddPublic(BuildMethodDecl(*method, types, true));
     call_enum->AddValue(
-        UpperCase(method->name.data),
+        UpperCase(method->GetName()),
         StringPrintf("android::IBinder::FIRST_CALL_TRANSACTION + %d",
-                     method->assigned_id));
+                     method->GetId()));
   }
   if_class->AddPublic(std::move(call_enum));
 
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 2150d48..5cfe034 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -270,11 +270,11 @@
     int i;
     bool hasOutParams = false;
 
-    const bool oneway = proxyClass->mOneWay || method.oneway;
+    const bool oneway = proxyClass->mOneWay || method.IsOneway();
 
     // == the TRANSACT_ constant =============================================
     string transactCodeName = "TRANSACTION_";
-    transactCodeName += method.name.data;
+    transactCodeName += method.GetName();
 
     char transactCodeValue[60];
     sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
@@ -288,11 +288,11 @@
     Method* decl = new Method;
         decl->comment = method.GetComments();
         decl->modifiers = PUBLIC;
-        decl->returnType = types->Find(method.type->GetName());
-        decl->returnTypeDimension = method.type->GetDimension();
-        decl->name = method.name.data;
+        decl->returnType = types->Find(method.GetType().GetName());
+        decl->returnTypeDimension = method.GetType().GetDimension();
+        decl->name = method.GetName();
 
-    for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
+    for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
         decl->parameters.push_back(new Variable(
                             types->Find(arg->GetType().GetName()), arg->GetName(),
                             arg->GetType().GetDimension()));
@@ -306,7 +306,7 @@
 
     Case* c = new Case(transactCodeName);
 
-    MethodCall* realCall = new MethodCall(THIS_VALUE, method.name.data);
+    MethodCall* realCall = new MethodCall(THIS_VALUE, method.GetName());
 
     // interface token validation is the very first thing we do
     c->statements->Add(new MethodCall(stubClass->transact_data,
@@ -315,7 +315,7 @@
     // args
     Variable* cl = NULL;
     VariableFactory stubArgs("_arg");
-    for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
+    for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
         const Type* t = types->Find(arg->GetType().GetName());
         Variable* v = stubArgs.Get(t);
         v->dimension = arg->GetType().GetDimension();
@@ -344,7 +344,7 @@
 
     // the real call
     Variable* _result = NULL;
-    if (method.type->GetName() == "void") {
+    if (method.GetType().GetName() == "void") {
         c->statements->Add(realCall);
 
         if (!oneway) {
@@ -373,7 +373,7 @@
 
     // out parameters
     i = 0;
-    for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
+    for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
         const Type* t = types->Find(arg->GetType().GetName());
         Variable* v = stubArgs.Get(i++);
 
@@ -393,11 +393,11 @@
     Method* proxy = new Method;
         proxy->comment = method.GetComments();
         proxy->modifiers = PUBLIC | OVERRIDE;
-        proxy->returnType = types->Find(method.type->GetName());
-        proxy->returnTypeDimension = method.type->GetDimension();
-        proxy->name = method.name.data;
+        proxy->returnType = types->Find(method.GetType().GetName());
+        proxy->returnTypeDimension = method.GetType().GetDimension();
+        proxy->name = method.GetName();
         proxy->statements = new StatementBlock;
-        for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
+        for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
             proxy->parameters.push_back(new Variable(
                             types->Find(arg->GetType().GetName()), arg->GetName(),
                             arg->GetType().GetDimension()));
@@ -420,9 +420,9 @@
 
     // the return value
     _result = NULL;
-    if (method.type->GetName() != "void") {
+    if (method.GetType().GetName() != "void") {
         _result = new Variable(proxy->returnType, "_result",
-                method.type->GetDimension());
+                method.GetType().GetDimension());
         proxy->statements->Add(new VariableDeclaration(_result));
     }
 
@@ -437,7 +437,7 @@
             1, new LiteralExpression("DESCRIPTOR")));
 
     // the parameters
-    for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
+    for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
         const Type* t = types->Find(arg->GetType().GetName());
         Variable* v = new Variable(t, arg->GetName(), arg->GetType().GetDimension());
         AidlArgument::Direction dir = arg->GetDirection();
@@ -478,7 +478,7 @@
         }
 
         // the out/inout parameters
-        for (const std::unique_ptr<AidlArgument>& arg : *method.args) {
+        for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
             const Type* t = types->Find(arg->GetType().GetName());
             Variable* v = new Variable(t, arg->GetName(), arg->GetType().GetDimension());
             if (arg->GetDirection() & AidlArgument::OUT_DIR) {
@@ -554,7 +554,7 @@
     int index = 0;
     for (const auto& item : *iface->methods) {
         generate_method(*item, interface, stub, proxy,
-                        item->assigned_id, types);
+                        item->GetId(), types);
         index++;
     }