Rev 2 of Thrift, the Pillar successor

Summary: End-to-end communications and serialization in C++ is working

Reviewed By: aditya

Test Plan: See the new top-level test/ folder. It vaguely resembles a unit test, though it could be more automated.

Revert Plan: Revertible

Notes: Still a LOT of optimization work to be done on the generated C++ code, which should be using dynamic memory in a number of places. Next major task is writing the PHP/Java/Python generators.




git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664712 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/src/parse/t_base_type.h b/compiler/src/parse/t_base_type.h
index bc96122..f6cc197 100644
--- a/compiler/src/parse/t_base_type.h
+++ b/compiler/src/parse/t_base_type.h
@@ -25,6 +25,7 @@
     t_type(name), base_(base) {}
     
   t_base get_base() const { return base_; }
+  bool is_void() const { return base_ == TYPE_VOID; }
   bool is_base_type() const { return true; }
     
  private:
diff --git a/compiler/src/parse/t_list.h b/compiler/src/parse/t_list.h
index 736ac48..65874cc 100644
--- a/compiler/src/parse/t_list.h
+++ b/compiler/src/parse/t_list.h
@@ -1,27 +1,19 @@
 #ifndef T_LIST_H
 #define T_LIST_H
 
-#include "t_field.h"
-#include <vector>
+#include "t_type.h"
 
-/**
- * List of elements.
- *
- * @author Mark Slee <mcslee@facebook.com>
- */
-class t_list {
+class t_list : public t_type {
  public:
-  t_list() {}
+  t_list(t_type* elem_type) : elem_type_(elem_type) {}
   ~t_list() {}
 
-  /** Add a new field to the list */
-  void append(t_field* elem) { list_.push_back(elem); }
-
-  /** Retrieve the list contents */
-  const std::vector<t_field*>& elems() const { return list_; }
+  t_type* get_elem_type() const { return elem_type_; }
+  bool is_list() const { return true; }
 
  private:
-  std::vector<t_field*> list_;
+  t_type* elem_type_;
 };
 
 #endif
+
diff --git a/compiler/src/parse/t_map.h b/compiler/src/parse/t_map.h
new file mode 100644
index 0000000..1f61843
--- /dev/null
+++ b/compiler/src/parse/t_map.h
@@ -0,0 +1,19 @@
+#ifndef T_MAP_H
+#define T_MAP_H
+
+class t_map : public t_type {
+ public:
+  t_map(t_type* key_type, t_type* val_type) :
+    key_type_(key_type), val_type_(val_type) {}
+  ~t_map() {}
+
+  t_type* get_key_type() const { return key_type_; }
+  t_type* get_val_type() const { return val_type_; }
+  bool is_map() const { return true; }
+
+ private:
+  t_type* key_type_;
+  t_type* val_type_;
+};
+
+#endif
diff --git a/compiler/src/parse/t_program.h b/compiler/src/parse/t_program.h
index fd35799..cda24c6 100644
--- a/compiler/src/parse/t_program.h
+++ b/compiler/src/parse/t_program.h
@@ -1,6 +1,7 @@
 #ifndef T_PROGRAM_H
 #define T_PROGRAM_H
 
+#include <map>
 #include <string>
 #include <vector>
 
@@ -9,6 +10,9 @@
 #include "t_enum.h"
 #include "t_struct.h"
 #include "t_service.h"
+#include "t_list.h"
+#include "t_map.h"
+#include "t_set.h"
 
 /**
  * Top level class representing an entire thrift program. A program consists
@@ -52,12 +56,6 @@
   const std::vector<t_struct*>&  get_structs()  const { return structs_;  }
   const std::vector<t_service*>& get_services() const { return services_; }
 
-  // New program element addition
-  void add_typedef(t_typedef *td) { typedefs_.push_back(td); }
-  void add_enum   (t_enum *te)    { enums_.push_back(te);    }
-  void add_struct (t_struct *ts)  { structs_.push_back(ts);  }
-  void add_service(t_service *ts) { services_.push_back(ts); }
-
   // Accessors for global types
   t_type* get_void_type()   const { return type_void;   }
   t_type* get_string_type() const { return type_string; }
@@ -67,6 +65,31 @@
   t_type* get_i64_type()    const { return type_i64;    }
   t_type* get_u64_type()    const { return type_u64;    }
 
+  // Custom data type lookup
+  void add_custom_type(std::string name, t_type* type) {
+    custom_types_[name] = type;
+  }
+  t_type* get_custom_type(std::string name) {
+    return custom_types_[name];
+  }
+
+  // New program element addition
+  void add_typedef(t_typedef* td) {
+    typedefs_.push_back(td);
+    add_custom_type(td->get_symbolic(), td);
+  }
+  void add_enum(t_enum* te) {
+    enums_.push_back(te);
+    add_custom_type(te->get_name(), te);
+  }
+  void add_struct(t_struct* ts) {
+    structs_.push_back(ts);
+    add_custom_type(ts->get_name(), ts);
+  }
+  void add_service(t_service* ts) {
+    services_.push_back(ts);
+  }
+
  private:
   // Name
   std::string name_;
@@ -76,7 +99,10 @@
   std::vector<t_enum*>    enums_;
   std::vector<t_struct*>  structs_;
   std::vector<t_service*> services_;
-  
+
+  // Type map
+  std::map<std::string, t_type*> custom_types_;
+
   // Global base types
   t_type* type_void;
   t_type* type_string;
diff --git a/compiler/src/parse/t_set.h b/compiler/src/parse/t_set.h
new file mode 100644
index 0000000..3d34ace
--- /dev/null
+++ b/compiler/src/parse/t_set.h
@@ -0,0 +1,18 @@
+#ifndef T_SET_H
+#define T_SET_H
+
+#include "t_type.h"
+
+class t_set : public t_type {
+ public:
+  t_set(t_type* elem_type) : elem_type_(elem_type) {}
+  ~t_set() {}
+
+  t_type* get_elem_type() const { return elem_type_; }
+  bool is_set() const { return true; }
+
+ private:
+  t_type* elem_type_;
+};
+
+#endif
diff --git a/compiler/src/parse/t_struct.h b/compiler/src/parse/t_struct.h
index fcc00e7..38eb750 100644
--- a/compiler/src/parse/t_struct.h
+++ b/compiler/src/parse/t_struct.h
@@ -5,19 +5,24 @@
 #include <string>
 
 #include "t_type.h"
-#include "t_list.h"
+#include "t_field.h"
 
 class t_struct : public t_type {
  public:
-  t_struct(std::string name, t_list* members) :
-    t_type(name), members_(members) {}
+  t_struct() {}
   ~t_struct() {}
 
-  t_list* get_members() { return members_; }
-  bool is_struct() { return true; }
+  /** Set the struct name */
+  void set_name(const std::string& name) { name_ = name; }
+
+  /** Add a new field to the list */
+  void append(t_field* elem) { members_.push_back(elem); }
+
+  const std::vector<t_field*>& get_members() { return members_; }
+  bool is_struct() const { return true; }
 
  private:
-  t_list* members_;
+  std::vector<t_field*> members_;
 };
 
 #endif
diff --git a/compiler/src/parse/t_type.h b/compiler/src/parse/t_type.h
index 436c59e..6703bfa 100644
--- a/compiler/src/parse/t_type.h
+++ b/compiler/src/parse/t_type.h
@@ -14,10 +14,16 @@
 
   virtual const std::string& get_name() const { return name_; }
 
+  virtual bool is_void()      const { return false; }
   virtual bool is_base_type() const { return false; }
   virtual bool is_typedef()   const { return false; }
   virtual bool is_enum()      const { return false; }
   virtual bool is_struct()    const { return false; }
+  virtual bool is_list()      const { return false; }
+  virtual bool is_set()       const { return false; }
+  virtual bool is_map()       const { return false; }
+
+  bool is_container() const { return is_map() || is_set() || is_list(); }
 
  protected:
   t_type() {}