Thrift compiler now enforces uniqueness of field identifiers

Summary: The code would either not generate, or generate code with errors, if you did this beforehand. Now it's a die-fast stop hard error since this is absolultely always a wrong thing to do.

Reviewed By: dreiss

Test Plan: Test compiling a .thrift file with a repeated field identifier in a struct or arglist.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665379 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/parse/t_field.h b/compiler/cpp/src/parse/t_field.h
index 25c50a5..35ee1a2 100644
--- a/compiler/cpp/src/parse/t_field.h
+++ b/compiler/cpp/src/parse/t_field.h
@@ -106,12 +106,12 @@
 
   bool has_doc() {
     return has_doc_;
-  }                                                           
+  }
 
-  void set_doc(const std::string& doc) {                      
-    doc_ = doc;                                               
-    has_doc_ = true;                                          
-  }                                                           
+  void set_doc(const std::string& doc) {
+    doc_ = doc;
+    has_doc_ = true;
+  }
 
   // This is not the same function as t_type::get_fingerprint_material,
   // but it does the same thing.
@@ -132,8 +132,8 @@
   bool xsd_nillable_;
   t_struct* xsd_attrs_;
 
-  std::string doc_;                                           
-  bool has_doc_;                                              
+  std::string doc_;
+  bool has_doc_;
 
 };
 
diff --git a/compiler/cpp/src/parse/t_struct.h b/compiler/cpp/src/parse/t_struct.h
index 39da110..bca51f6 100644
--- a/compiler/cpp/src/parse/t_struct.h
+++ b/compiler/cpp/src/parse/t_struct.h
@@ -85,6 +85,17 @@
     }
   }
 
+  bool validate_field(t_field* field) {
+    int key = field->get_key();
+    std::vector<t_field*>::const_iterator m_iter;
+    for (m_iter = members_.begin(); m_iter != members_.end(); ++m_iter) {
+      if ((*m_iter)->get_key() == key) {
+        return false;
+      }
+    }
+    return true;
+  }
+
  private:
 
   std::vector<t_field*> members_;
diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy
index 5d7cfcc..21828ff 100644
--- a/compiler/cpp/src/thrifty.yy
+++ b/compiler/cpp/src/thrifty.yy
@@ -761,6 +761,10 @@
     {
       pdebug("FieldList -> FieldList , Field");
       $$ = $1;
+      if (!($$->validate_field($2))) {
+        yyerror("Field identifier %d for \"%s\" has already been used", $2->get_key(), $2->get_name().c_str());
+        exit(1);
+      }
       $$->append($2);
     }
 |