THRIFT-3834 Erlang namespacing and exception metadata
Client: Erlang
Patch: Steve Cohen
diff --git a/compiler/cpp/src/generate/t_erl_generator.cc b/compiler/cpp/src/generate/t_erl_generator.cc
index 0e7f7f1..9118b48 100644
--- a/compiler/cpp/src/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/generate/t_erl_generator.cc
@@ -56,6 +56,8 @@
     legacy_names_ = false;
     maps_ = false;
     otp16_ = false;
+    erl_namespace_ = program->get_namespace("erl");
+
     for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
       if( iter->first.compare("legacynames") == 0) {
         legacy_names_ = true;
@@ -64,7 +66,7 @@
       } else if( iter->first.compare("otp16") == 0) {
         otp16_ = true;
       } else {
-        throw "unknown option erl:" + iter->first; 
+        throw "unknown option erl:" + iter->first;
       }
     }
 
@@ -180,6 +182,8 @@
   /* if true use non-namespaced dict and set instead of dict:dict and sets:set */
   bool otp16_;
 
+  /* A namespace that gets appended to our generated structs. */
+  std::string erl_namespace_;
   /**
    * add function to export list
    */
@@ -227,6 +231,7 @@
    */
   std::vector<std::string> v_struct_names_;
   std::vector<std::string> v_enum_names_;
+  std::vector<std::string> v_exception_names_;
   std::vector<t_enum*> v_enums_;
 };
 
@@ -339,6 +344,7 @@
   export_types_string("enum_info", 1);
   export_types_string("enum_names", 0);
   export_types_string("struct_names", 0);
+  export_types_string("exception_names", 0);
 
   f_types_file_ << "-export([" << export_types_lines_.str() << "])." << endl << endl;
 
@@ -351,6 +357,7 @@
   generate_type_metadata("struct_names", v_struct_names_);
   generate_enum_metadata();
   generate_type_metadata("enum_names", v_enum_names_);
+  generate_type_metadata("exception_names", v_exception_names_);
 
   hrl_footer(f_types_hrl_file_, string("BOGUS"));
 
@@ -369,7 +376,7 @@
 
 
   for(size_t i=0; i < num_structs; i++) {
-    f_types_file_ << atomify(names.at(i));
+    f_types_file_ << names.at(i);
 
     if (i < num_structs - 1) {
       f_types_file_ << ", ";
@@ -400,7 +407,7 @@
   vector<t_enum_value*>::iterator c_iter;
 
   v_enums_.push_back(tenum);
-  v_enum_names_.push_back(tenum->get_name());
+  v_enum_names_.push_back(atomify(tenum->get_name()));
 
   for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
     int value = (*c_iter)->get_value();
@@ -497,7 +504,7 @@
     indent(out) << value->get_integer();
 
   } else if (type->is_struct() || type->is_xception()) {
-    out << "#" << atomify(type->get_name()) << "{";
+    out << "#" << type_name(type) << "{";
     const vector<t_field*>& fields = ((t_struct*)type)->get_members();
     vector<t_field*>::const_iterator f_iter;
     const map<t_const_value*, t_const_value*>& val = value->get_map();
@@ -582,7 +589,7 @@
 string t_erl_generator::render_default_value(t_field* field) {
   t_type* type = field->get_type();
   if (type->is_struct() || type->is_xception()) {
-    return "#" + atomify(type->get_name()) + "{}";
+    return "#" + type_name(type) + "{}";
   } else if (type->is_map()) {
     if (maps_) {
       return "#{}";
@@ -620,7 +627,7 @@
   } else if (type->is_enum()) {
     return "integer()";
   } else if (type->is_struct() || type->is_xception()) {
-    return atomify(type->get_name()) + "()";
+    return type_name(type) + "()";
   } else if (type->is_map()) {
     if (maps_) {
       return "#{}";
@@ -657,7 +664,7 @@
  * Generates a struct
  */
 void t_erl_generator::generate_struct(t_struct* tstruct) {
-  v_struct_names_.push_back(tstruct->get_name());
+  v_struct_names_.push_back(type_name(tstruct));
   generate_erl_struct(tstruct, false);
 }
 
@@ -668,6 +675,7 @@
  * @param txception The struct definition
  */
 void t_erl_generator::generate_xception(t_struct* txception) {
+  v_exception_names_.push_back(type_name(txception));
   generate_erl_struct(txception, true);
 }
 
@@ -1009,6 +1017,10 @@
 
 string t_erl_generator::type_name(t_type* ttype) {
   string prefix = "";
+  if (erl_namespace_.length() > 0) {
+    prefix = erl_namespace_ + ".";
+  }
+
   string name = ttype->get_name();
 
   if (ttype->is_struct() || ttype->is_xception() || ttype->is_service()) {