Update thrift compiler for new syntax, generate new form of C++ code

Reviewed By: wayne, he loves less warnings


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664840 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/parse/t_enum.h b/compiler/cpp/src/parse/t_enum.h
index 4b6fe36..002ca82 100644
--- a/compiler/cpp/src/parse/t_enum.h
+++ b/compiler/cpp/src/parse/t_enum.h
@@ -11,7 +11,8 @@
  */
 class t_enum : public t_type {
  public:
-  t_enum() {}
+  t_enum(t_program* program) :
+    t_type(program) {}
 
   void set_name(std::string name) {
     name_ = name;
diff --git a/compiler/cpp/src/parse/t_function.h b/compiler/cpp/src/parse/t_function.h
index 3d07171..6f06abe 100644
--- a/compiler/cpp/src/parse/t_function.h
+++ b/compiler/cpp/src/parse/t_function.h
@@ -22,7 +22,7 @@
     name_(name),
     arglist_(arglist),
     async_(async) {
-    xceptions_ = new t_struct;
+    xceptions_ = new t_struct(NULL);
   }
 
   t_function(t_type* returntype,
diff --git a/compiler/cpp/src/parse/t_program.h b/compiler/cpp/src/parse/t_program.h
index 5e58654..a3270ad 100644
--- a/compiler/cpp/src/parse/t_program.h
+++ b/compiler/cpp/src/parse/t_program.h
@@ -5,6 +5,10 @@
 #include <string>
 #include <vector>
 
+// For program_name()
+#include "main.h"
+
+#include "t_scope.h"
 #include "t_base_type.h"
 #include "t_typedef.h"
 #include "t_enum.h"
@@ -30,38 +34,26 @@
  */
 class t_program {
  public:
-  t_program(std::string name) :
-    name_(name),
-    namespace_() {
-    type_void   = new t_base_type("void",   t_base_type::TYPE_VOID);
-    type_string = new t_base_type("string", t_base_type::TYPE_STRING);
-    type_bool   = new t_base_type("bool",   t_base_type::TYPE_BOOL);
-    type_byte   = new t_base_type("byte",   t_base_type::TYPE_BYTE);
-    type_i16    = new t_base_type("i16",    t_base_type::TYPE_I16);
-    type_i32    = new t_base_type("i32",    t_base_type::TYPE_I32);
-    type_i64    = new t_base_type("i64",    t_base_type::TYPE_I64);
-    type_double = new t_base_type("double", t_base_type::TYPE_DOUBLE);
+  t_program(std::string path, std::string name) :
+    path_(path), 
+    name_(name) {
+    scope_ = new t_scope();
   }
 
-  ~t_program() {
-    delete type_string;
-    delete type_bool;
-    delete type_byte;
-    delete type_i16;
-    delete type_i32;
-    delete type_i64;
-    delete type_double;
+  t_program(std::string path) :
+    path_(path) {
+    name_ = program_name(path);
+    scope_ = new t_scope();
   }
 
+  // Path accessor   
+  const std::string& get_path() const { return path_; }
+
   // Name accessor
-  const std::string& get_name() const {
-    return name_;
-  }
+  const std::string& get_name() const { return name_; }
 
   // Namespace
-  const std::string& get_namespace() const {
-    return namespace_;
-  }
+  const std::string& get_namespace() const { return namespace_; }
 
   // Accessors for program elements
   const std::vector<t_typedef*>& get_typedefs()  const { return typedefs_;  }
@@ -70,57 +62,67 @@
   const std::vector<t_struct*>&  get_xceptions() const { return xceptions_; }
   const std::vector<t_service*>& get_services()  const { return services_;  }
 
-  // Accessors for global types
-  t_type* get_void_type()   const { return type_void;   }
-  t_type* get_string_type() const { return type_string; }
-  t_type* get_bool_type()   const { return type_bool;   }
-  t_type* get_byte_type()   const { return type_byte;   }
-  t_type* get_i16_type()    const { return type_i16;    }
-  t_type* get_i32_type()    const { return type_i32;    }
-  t_type* get_i64_type()    const { return type_i64;    }
-  t_type* get_double_type() const { return type_double; }
+  // Program elements
+  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_xception (t_struct*  tx) { xceptions_.push_back(tx); }
+  void add_service  (t_service* ts) { services_.push_back(ts);  }
 
-  // Custom data type lookup
-  t_type* get_custom_type(std::string name) {
-    return custom_types_[name];
-  }
+  // Programs to include
+  const std::vector<t_program*>& get_includes() const { return includes_; }
 
-  // New program element addition
-
+  // Scoping and namespacing
   void set_namespace(std::string name) {
     namespace_ = name;
   }
 
-  void add_typedef(t_typedef* td) {
-    typedefs_.push_back(td);
-    add_custom_type(td->get_symbolic(), td);
+  // Scope accessor
+  t_scope* scope() {
+    return scope_;
   }
 
-  void add_enum(t_enum* te) {
-    enums_.push_back(te);
-    add_custom_type(te->get_name(), te);
+  // Includes
+
+  void add_include(std::string path) {
+    includes_.push_back(new t_program(path));
   }
 
-  void add_struct(t_struct* ts) {
-    structs_.push_back(ts);
-    add_custom_type(ts->get_name(), ts);
+  std::vector<t_program*>& get_includes() {
+    return includes_;
   }
 
-  void add_xception(t_struct* tx) {
-    xceptions_.push_back(tx);
-    add_custom_type(tx->get_name(), tx);
+  // Language specific namespace / packaging
+
+  void set_cpp_namespace(std::string cpp_namespace) {
+    cpp_namespace_ = cpp_namespace;
   }
 
-  void add_service(t_service* ts) {
-    services_.push_back(ts);
+  const std::string& get_cpp_namespace() const {
+    return cpp_namespace_;
   }
 
+  void add_cpp_include(std::string path) {
+    cpp_includes_.push_back(path);
+  }
+
+  const std::vector<std::string>& get_cpp_includes() {
+    return cpp_includes_;
+  }
+
+  void set_java_package(std::string java_package) {
+    java_package_ = java_package;
+  }
+
+  const std::string& get_java_package() const {
+    return java_package_;
+  }
+
+
  private:
 
-  // Add custom type for lookup
-  void add_custom_type(std::string name, t_type* type) {
-    custom_types_[name] = type;
-  }
+  // File path
+  std::string path_;
 
   // Name
   std::string name_;
@@ -128,25 +130,28 @@
   // Namespace
   std::string namespace_;
 
-  // Components
-  std::vector<t_typedef*>  typedefs_;
-  std::vector<t_enum*>     enums_;
-  std::vector<t_struct*>   structs_;
-  std::vector<t_struct*>   xceptions_;
-  std::vector<t_service*>  services_;
+  // Included programs
+  std::vector<t_program*> includes_;
 
-  // Type map
-  std::map<std::string, t_type*> custom_types_;
+  // Identifier lookup scope
+  t_scope* scope_;
 
-  // Global base types
-  t_type* type_void;
-  t_type* type_string;
-  t_type* type_bool;
-  t_type* type_byte;
-  t_type* type_i16;
-  t_type* type_i32;
-  t_type* type_i64;
-  t_type* type_double;
+  // Components to generate code for
+  std::vector<t_typedef*> typedefs_;
+  std::vector<t_enum*>    enums_;
+  std::vector<t_struct*>  structs_;
+  std::vector<t_struct*>  xceptions_;
+  std::vector<t_service*> services_;
+
+  // C++ namespace
+  std::string cpp_namespace_;
+
+  // C++ extra includes
+  std::vector<std::string> cpp_includes_;
+
+  // Java package
+  std::string java_package_;
+
 };
 
 #endif
diff --git a/compiler/cpp/src/parse/t_scope.h b/compiler/cpp/src/parse/t_scope.h
new file mode 100644
index 0000000..504393b
--- /dev/null
+++ b/compiler/cpp/src/parse/t_scope.h
@@ -0,0 +1,57 @@
+#ifndef T_SCOPE_H
+#define T_SCOPE_H
+
+#include <map>
+#include <string>
+
+#include "t_type.h"
+#include "t_service.h"
+
+/**
+ * This represents a variable scope used for looking up predefined types and
+ * services. Typically, a scope is associated with a t_program. Scopes are not
+ * used to determine code generation, but rather to resolve identifiers at
+ * parse time.
+ *
+ * @author Mark Slee <mcslee@facebook.com>
+ */
+class t_scope {
+ public:
+  t_scope() {}
+
+  void add_type(std::string name, t_type* type) {
+    types_[name] = type;
+  }
+
+  t_type* get_type(std::string name) {
+    return types_[name];
+  }
+
+  void add_service(std::string name, t_service* service) {
+    services_[name] = service;
+  }
+
+  t_service* get_service(std::string name) {
+    return services_[name];
+  }
+
+  void print() {
+    std::map<std::string, t_type*>::iterator iter;
+    for (iter = types_.begin(); iter != types_.end(); ++iter) {
+      printf("%s => %s\n",
+             iter->first.c_str(),
+             iter->second->get_name().c_str());
+    }
+  }
+
+ private:
+  
+  // Map of names to types
+  std::map<std::string, t_type*> types_;
+
+  // Map of names to services
+  std::map<std::string, t_service*> services_; 
+ 
+};
+
+#endif
diff --git a/compiler/cpp/src/parse/t_service.h b/compiler/cpp/src/parse/t_service.h
index 6bb5e5d..52280a4 100644
--- a/compiler/cpp/src/parse/t_service.h
+++ b/compiler/cpp/src/parse/t_service.h
@@ -4,34 +4,42 @@
 #include "t_function.h"
 #include <vector>
 
+class t_program;
+
 /**
  * A service consists of a set of functions.
  *
  * @author Mark Slee <mcslee@facebook.com>
  */
-class t_service {
+class t_service : public t_type {
  public:
-  t_service() {}
+  t_service(t_program* program) :
+    t_type(program),
+    extends_(NULL) {}
 
-  void set_name(std::string name) {
-    name_ = name;
+  bool is_service() const {
+    return true;
+  }
+
+  void set_extends(t_service* extends) {
+    extends_ = extends;
   }
 
   void add_function(t_function* func) {
     functions_.push_back(func);
   }
 
-  const std::string& get_name() const {
-    return name_;
-  }
-
   const std::vector<t_function*>& get_functions() const {
     return functions_;
   }
 
+  t_service* get_extends() {
+    return extends_;
+  }
+
  private:
-  std::string name_;
   std::vector<t_function*> functions_;
+  t_service* extends_;
 };
 
 #endif
diff --git a/compiler/cpp/src/parse/t_struct.h b/compiler/cpp/src/parse/t_struct.h
index 8768c5f..ce5f752 100644
--- a/compiler/cpp/src/parse/t_struct.h
+++ b/compiler/cpp/src/parse/t_struct.h
@@ -7,6 +7,9 @@
 #include "t_type.h"
 #include "t_field.h"
 
+// Forward declare that puppy
+class t_program;
+
 /**
  * A struct is a container for a set of member fields that has a name. Structs
  * are also used to implement exception types.
@@ -15,11 +18,12 @@
  */
 class t_struct : public t_type {
  public:
-  t_struct() :
+  t_struct(t_program* program) :
+    t_type(program),
     is_xception_(false) {}
 
-  t_struct(const std::string& name) :
-    t_type(name),
+  t_struct(t_program* program, const std::string& name) :
+    t_type(program, name),
     is_xception_(false) {}
 
   void set_name(const std::string& name) {
diff --git a/compiler/cpp/src/parse/t_type.h b/compiler/cpp/src/parse/t_type.h
index 1d0a2ed..9589f02 100644
--- a/compiler/cpp/src/parse/t_type.h
+++ b/compiler/cpp/src/parse/t_type.h
@@ -3,6 +3,8 @@
 
 #include <string>
 
+class t_program;
+
 /**
  * Generic representation of a thrift type. These objects are used by the
  * parser module to build up a tree of object that are all explicitly typed.
@@ -16,7 +18,13 @@
  public:
   virtual ~t_type() {}
 
-  virtual const std::string& get_name() const { return name_; }
+  virtual void set_name(std::string name) {
+    name_ = name;
+  }
+
+  virtual const std::string& get_name() const {
+    return name_;
+  }
 
   virtual bool is_void()      const { return false; }
   virtual bool is_base_type() const { return false; }
@@ -28,13 +36,26 @@
   virtual bool is_list()      const { return false; }
   virtual bool is_set()       const { return false; }
   virtual bool is_map()       const { return false; }
+  virtual bool is_service()   const { return false; }
+
+  t_program* get_program() {
+    return program_;
+  }
 
  protected:
   t_type() {}
 
-  t_type(std::string name) :
+  t_type(t_program* program) :
+    program_(program) {}
+
+  t_type(t_program* program, std::string name) :
+    program_(program),
     name_(name) {}
 
+  t_type(std::string name) :
+    name_(name) {}
+    
+  t_program* program_;
   std::string name_;
 };
 
diff --git a/compiler/cpp/src/parse/t_typedef.h b/compiler/cpp/src/parse/t_typedef.h
index 8973201..cc7f25c 100644
--- a/compiler/cpp/src/parse/t_typedef.h
+++ b/compiler/cpp/src/parse/t_typedef.h
@@ -14,8 +14,8 @@
  */
 class t_typedef : public t_type {
  public:
-  t_typedef(t_type* type, std::string symbolic) :
-    t_type(symbolic),
+  t_typedef(t_program* program, t_type* type, std::string symbolic) :
+    t_type(program, symbolic),
     type_(type),
     symbolic_(symbolic) {}