hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [38/51] [abbrv] [partial] incubator-hawq git commit: HAWQ-735. Import thrift-0.9.3 into depends/thirdparty/thrift folder
Date Wed, 18 May 2016 02:50:51 GMT
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/generate/t_erl_generator.cc
----------------------------------------------------------------------
diff --git a/depends/thirdparty/thrift/compiler/cpp/src/generate/t_erl_generator.cc b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_erl_generator.cc
new file mode 100644
index 0000000..c066636
--- /dev/null
+++ b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_erl_generator.cc
@@ -0,0 +1,1044 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sstream>
+#include "t_generator.h"
+#include "platform.h"
+#include "version.h"
+
+using std::map;
+using std::ofstream;
+using std::ostream;
+using std::ostringstream;
+using std::string;
+using std::stringstream;
+using std::vector;
+
+static const std::string endl = "\n"; // avoid ostream << std::endl flushes
+
+/**
+ * Erlang code generator.
+ *
+ */
+class t_erl_generator : public t_generator {
+public:
+  t_erl_generator(t_program* program,
+                  const std::map<std::string, std::string>& parsed_options,
+                  const std::string& option_string)
+    : t_generator(program) {
+    (void)parsed_options;
+    (void)option_string;
+    out_dir_base_ = "gen-erl";
+
+    legacy_names_ = (parsed_options.find("legacynames") != parsed_options.end());
+    maps_ = (parsed_options.find("maps") != parsed_options.end());
+    otp16_ = (parsed_options.find("otp16") != parsed_options.end());
+    if (maps_ && otp16_) {
+      throw "argument error: Cannot specify both maps and otp16; maps are not available for Erlang/OTP R16 or older";
+    }
+  }
+
+  /**
+   * Init and close methods
+   */
+
+  void init_generator();
+  void close_generator();
+
+  /**
+   * Program-level generation functions
+   */
+
+  void generate_typedef(t_typedef* ttypedef);
+  void generate_enum(t_enum* tenum);
+  void generate_const(t_const* tconst);
+  void generate_struct(t_struct* tstruct);
+  void generate_xception(t_struct* txception);
+  void generate_service(t_service* tservice);
+  void generate_member_type(std::ostream& out, t_type* type);
+  void generate_member_value(std::ostream& out, t_type* type, t_const_value* value);
+
+  std::string render_member_type(t_field* field);
+  std::string render_member_value(t_field* field);
+  std::string render_member_requiredness(t_field* field);
+
+  //  std::string render_default_value(t_type* type);
+  std::string render_default_value(t_field* field);
+  std::string render_const_value(t_type* type, t_const_value* value);
+  std::string render_type_term(t_type* ttype, bool expand_structs, bool extended_info = false);
+
+  /**
+   * Struct generation code
+   */
+
+  void generate_erl_struct(t_struct* tstruct, bool is_exception);
+  void generate_erl_struct_definition(std::ostream& out, t_struct* tstruct);
+  void generate_erl_struct_member(std::ostream& out, t_field* tmember);
+  void generate_erl_struct_info(std::ostream& out, t_struct* tstruct);
+  void generate_erl_extended_struct_info(std::ostream& out, t_struct* tstruct);
+  void generate_erl_function_helpers(t_function* tfunction);
+
+  /**
+   * Service-level generation functions
+   */
+
+  void generate_service_helpers(t_service* tservice);
+  void generate_service_interface(t_service* tservice);
+  void generate_function_info(t_service* tservice, t_function* tfunction);
+
+  /**
+   * Helper rendering functions
+   */
+
+  std::string erl_autogen_comment();
+  std::string erl_imports();
+  std::string render_includes();
+  std::string type_name(t_type* ttype);
+
+  std::string function_signature(t_function* tfunction, std::string prefix = "");
+
+  std::string argument_list(t_struct* tstruct);
+  std::string type_to_enum(t_type* ttype);
+  std::string type_module(t_type* ttype);
+
+  std::string make_safe_for_module_name(std::string in) {
+    if (legacy_names_) {
+      return decapitalize(in);
+    } else {
+      return underscore(in);
+    }
+  }
+
+  std::string atomify(std::string in) {
+    if (legacy_names_) {
+      return "'" + decapitalize(in) + "'";
+    } else {
+      return "'" + in + "'";
+    }
+  }
+
+  std::string constify(std::string in) {
+    if (legacy_names_) {
+      return capitalize(in);
+    } else {
+      return uppercase(in);
+    }
+  }
+
+  static std::string comment(string in);
+
+private:
+  bool has_default_value(t_field*);
+
+  /* if true retain pre 0.9.2 naming scheme for functions, atoms and consts */
+  bool legacy_names_;
+
+  /* if true use maps instead of dicts in generated code */
+  bool maps_;
+
+  /* if true use non-namespaced dict and set instead of dict:dict and sets:set */
+  bool otp16_;
+
+  /**
+   * add function to export list
+   */
+
+  void export_function(t_function* tfunction, std::string prefix = "");
+  void export_string(std::string name, int num);
+
+  void export_types_function(t_function* tfunction, std::string prefix = "");
+  void export_types_string(std::string name, int num);
+
+  /**
+   * write out headers and footers for hrl files
+   */
+
+  void hrl_header(std::ostream& out, std::string name);
+  void hrl_footer(std::ostream& out, std::string name);
+
+  /**
+   * stuff to spit out at the top of generated files
+   */
+
+  bool export_lines_first_;
+  std::ostringstream export_lines_;
+
+  bool export_types_lines_first_;
+  std::ostringstream export_types_lines_;
+
+  /**
+   * File streams
+   */
+
+  std::ostringstream f_info_;
+  std::ostringstream f_info_ext_;
+
+  std::ofstream f_types_file_;
+  std::ofstream f_types_hrl_file_;
+
+  std::ofstream f_consts_;
+  std::ostringstream f_service_;
+  std::ofstream f_service_file_;
+  std::ofstream f_service_hrl_;
+};
+
+/**
+ * UI for file generation by opening up the necessary file output
+ * streams.
+ *
+ * @param tprogram The program to generate
+ */
+void t_erl_generator::init_generator() {
+  // Make output directory
+  MKDIR(get_out_dir().c_str());
+
+  // setup export lines
+  export_lines_first_ = true;
+  export_types_lines_first_ = true;
+
+  // types files
+  string f_types_name = get_out_dir() + make_safe_for_module_name(program_name_) + "_types.erl";
+  string f_types_hrl_name = get_out_dir() + make_safe_for_module_name(program_name_) + "_types.hrl";
+
+  f_types_file_.open(f_types_name.c_str());
+  f_types_hrl_file_.open(f_types_hrl_name.c_str());
+
+  hrl_header(f_types_hrl_file_, make_safe_for_module_name(program_name_) + "_types");
+
+  f_types_file_ << erl_autogen_comment() << endl << "-module("
+                << make_safe_for_module_name(program_name_) << "_types)." << endl << erl_imports()
+                << endl;
+
+  f_types_file_ << "-include(\"" << make_safe_for_module_name(program_name_) << "_types.hrl\")."
+                << endl << endl;
+
+  f_types_hrl_file_ << render_includes() << endl;
+
+  // consts file
+  string f_consts_name = get_out_dir() + make_safe_for_module_name(program_name_)
+                         + "_constants.hrl";
+  f_consts_.open(f_consts_name.c_str());
+
+  f_consts_ << erl_autogen_comment() << endl << erl_imports() << endl << "-include(\""
+            << make_safe_for_module_name(program_name_) << "_types.hrl\")." << endl << endl;
+}
+
+/**
+ * Boilerplate at beginning and end of header files
+ */
+void t_erl_generator::hrl_header(ostream& out, string name) {
+  out << "-ifndef(_" << name << "_included)." << endl << "-define(_" << name << "_included, yeah)."
+      << endl;
+}
+
+void t_erl_generator::hrl_footer(ostream& out, string name) {
+  (void)name;
+  out << "-endif." << endl;
+}
+
+/**
+ * Renders all the imports necessary for including another Thrift program
+ */
+string t_erl_generator::render_includes() {
+  const vector<t_program*>& includes = program_->get_includes();
+  string result = "";
+  for (size_t i = 0; i < includes.size(); ++i) {
+    result += "-include(\"" + make_safe_for_module_name(includes[i]->get_name())
+              + "_types.hrl\").\n";
+  }
+  if (includes.size() > 0) {
+    result += "\n";
+  }
+  return result;
+}
+
+/**
+ * Autogen'd comment
+ */
+string t_erl_generator::erl_autogen_comment() {
+  return std::string("%%\n") + "%% Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")\n"
+         + "%%\n" + "%% DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n"
+         + "%%\n";
+}
+
+/**
+ * Comment out text
+ */
+
+string t_erl_generator::comment(string in) {
+  size_t pos = 0;
+  in.insert(pos, "%% ");
+  while ((pos = in.find_first_of('\n', pos)) != string::npos) {
+    in.insert(++pos, "%% ");
+  }
+  return in;
+}
+
+/**
+ * Prints standard thrift imports
+ */
+string t_erl_generator::erl_imports() {
+  return "";
+}
+
+/**
+ * Closes the type files
+ */
+void t_erl_generator::close_generator() {
+
+  export_types_string("struct_info", 1);
+  export_types_string("struct_info_ext", 1);
+  f_types_file_ << "-export([" << export_types_lines_.str() << "])." << endl << endl;
+
+  f_types_file_ << f_info_.str();
+  f_types_file_ << "struct_info(_) -> erlang:error(function_clause)." << endl << endl;
+
+  f_types_file_ << f_info_ext_.str();
+  f_types_file_ << "struct_info_ext(_) -> erlang:error(function_clause)." << endl << endl;
+
+  hrl_footer(f_types_hrl_file_, string("BOGUS"));
+
+  f_types_file_.close();
+  f_types_hrl_file_.close();
+  f_consts_.close();
+}
+
+/**
+ * Generates a typedef. no op
+ *
+ * @param ttypedef The type definition
+ */
+void t_erl_generator::generate_typedef(t_typedef* ttypedef) {
+  (void)ttypedef;
+}
+
+/**
+ * Generates code for an enumerated type. Done using a class to scope
+ * the values.
+ *
+ * @param tenum The enumeration
+ */
+void t_erl_generator::generate_enum(t_enum* tenum) {
+  vector<t_enum_value*> constants = tenum->get_constants();
+  vector<t_enum_value*>::iterator c_iter;
+
+  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
+    int value = (*c_iter)->get_value();
+    string name = (*c_iter)->get_name();
+    indent(f_types_hrl_file_) << "-define(" << constify(make_safe_for_module_name(program_name_))
+                              << "_" << constify(tenum->get_name()) << "_" << constify(name) << ", "
+                              << value << ")." << endl;
+  }
+
+  f_types_hrl_file_ << endl;
+}
+
+/**
+ * Generate a constant value
+ */
+void t_erl_generator::generate_const(t_const* tconst) {
+  t_type* type = tconst->get_type();
+  string name = tconst->get_name();
+  t_const_value* value = tconst->get_value();
+
+  f_consts_ << "-define(" << constify(make_safe_for_module_name(program_name_)) << "_"
+            << constify(name) << ", " << render_const_value(type, value) << ")." << endl << endl;
+}
+
+/**
+ * Prints the value of a constant with the given type. Note that type checking
+ * is NOT performed in this function as it is always run beforehand using the
+ * validate_types method in main.cc
+ */
+string t_erl_generator::render_const_value(t_type* type, t_const_value* value) {
+  type = get_true_type(type);
+  std::ostringstream out;
+
+  if (type->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
+    switch (tbase) {
+    case t_base_type::TYPE_STRING:
+      out << '"' << get_escaped_string(value) << '"';
+      break;
+    case t_base_type::TYPE_BOOL:
+      out << (value->get_integer() > 0 ? "true" : "false");
+      break;
+    case t_base_type::TYPE_BYTE:
+    case t_base_type::TYPE_I16:
+    case t_base_type::TYPE_I32:
+    case t_base_type::TYPE_I64:
+      out << value->get_integer();
+      break;
+    case t_base_type::TYPE_DOUBLE:
+      if (value->get_type() == t_const_value::CV_INTEGER) {
+        out << value->get_integer();
+      } else {
+        out << value->get_double();
+      }
+      break;
+    default:
+      throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
+    }
+  } else if (type->is_enum()) {
+    indent(out) << value->get_integer();
+
+  } else if (type->is_struct() || type->is_xception()) {
+    out << "#" << atomify(type->get_name()) << "{";
+    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();
+    map<t_const_value*, t_const_value*>::const_iterator v_iter;
+
+    bool first = true;
+    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
+      t_type* field_type = NULL;
+      for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+        if ((*f_iter)->get_name() == v_iter->first->get_string()) {
+          field_type = (*f_iter)->get_type();
+        }
+      }
+      if (field_type == NULL) {
+        throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
+      }
+
+      if (first) {
+        first = false;
+      } else {
+        out << ",";
+      }
+      out << v_iter->first->get_string();
+      out << " = ";
+      out << render_const_value(field_type, v_iter->second);
+    }
+    indent_down();
+    indent(out) << "}";
+
+  } else if (type->is_map()) {
+    t_type* ktype = ((t_map*)type)->get_key_type();
+    t_type* vtype = ((t_map*)type)->get_val_type();
+
+    if (maps_) {
+      out << "maps:from_list([";
+    } else {
+      out << "dict:from_list([";
+    }
+    map<t_const_value*, t_const_value*>::const_iterator i, end = value->get_map().end();
+    for (i = value->get_map().begin(); i != end;) {
+      out << "{" << render_const_value(ktype, i->first) << ","
+          << render_const_value(vtype, i->second) << "}";
+      if (++i != end) {
+        out << ",";
+      }
+    }
+    out << "])";
+  } else if (type->is_set()) {
+    t_type* etype = ((t_set*)type)->get_elem_type();
+    out << "sets:from_list([";
+    vector<t_const_value*>::const_iterator i, end = value->get_list().end();
+    for (i = value->get_list().begin(); i != end;) {
+      out << render_const_value(etype, *i);
+      if (++i != end) {
+        out << ",";
+      }
+    }
+    out << "])";
+  } else if (type->is_list()) {
+    t_type* etype;
+    etype = ((t_list*)type)->get_elem_type();
+    out << "[";
+
+    bool first = true;
+    const vector<t_const_value*>& val = value->get_list();
+    vector<t_const_value*>::const_iterator v_iter;
+    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
+      if (first) {
+        first = false;
+      } else {
+        out << ",";
+      }
+      out << render_const_value(etype, *v_iter);
+    }
+    out << "]";
+  } else {
+    throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
+  }
+  return out.str();
+}
+
+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()) + "{}";
+  } else if (type->is_map()) {
+    if (maps_) {
+      return "#{}";
+    } else {
+      return "dict:new()";
+    }
+  } else if (type->is_set()) {
+    return "sets:new()";
+  } else if (type->is_list()) {
+    return "[]";
+  } else {
+    return "undefined";
+  }
+}
+
+string t_erl_generator::render_member_type(t_field* field) {
+  t_type* type = get_true_type(field->get_type());
+  if (type->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
+    switch (tbase) {
+    case t_base_type::TYPE_STRING:
+      return "string() | binary()";
+    case t_base_type::TYPE_BOOL:
+      return "boolean()";
+    case t_base_type::TYPE_BYTE:
+    case t_base_type::TYPE_I16:
+    case t_base_type::TYPE_I32:
+    case t_base_type::TYPE_I64:
+      return "integer()";
+    case t_base_type::TYPE_DOUBLE:
+      return "float()";
+    default:
+      throw "compiler error: unsupported base type " + t_base_type::t_base_name(tbase);
+    }
+  } else if (type->is_enum()) {
+    return "integer()";
+  } else if (type->is_struct() || type->is_xception()) {
+    return atomify(type->get_name()) + "()";
+  } else if (type->is_map()) {
+    if (maps_) {
+      return "#{}";
+    } else if (otp16_) {
+      return "dict()";
+    } else {
+      return "dict:dict()";
+    }
+  } else if (type->is_set()) {
+    if (otp16_) {
+      return "set()";
+    } else {
+      return "sets:set()";
+    }
+  } else if (type->is_list()) {
+    return "list()";
+  } else {
+    throw "compiler error: unsupported type " + type->get_name();
+  }
+}
+
+string t_erl_generator::render_member_requiredness(t_field* field) {
+  switch (field->get_req()) {
+  case t_field::T_REQUIRED:
+    return "required";
+  case t_field::T_OPTIONAL:
+    return "optional";
+  default:
+    return "undefined";
+  }
+}
+
+/**
+ * Generates a struct
+ */
+void t_erl_generator::generate_struct(t_struct* tstruct) {
+  generate_erl_struct(tstruct, false);
+}
+
+/**
+ * Generates a struct definition for a thrift exception. Basically the same
+ * as a struct but extends the Exception class.
+ *
+ * @param txception The struct definition
+ */
+void t_erl_generator::generate_xception(t_struct* txception) {
+  generate_erl_struct(txception, true);
+}
+
+/**
+ * Generates a struct
+ */
+void t_erl_generator::generate_erl_struct(t_struct* tstruct, bool is_exception) {
+  (void)is_exception;
+  generate_erl_struct_definition(f_types_hrl_file_, tstruct);
+  generate_erl_struct_info(f_info_, tstruct);
+  generate_erl_extended_struct_info(f_info_ext_, tstruct);
+}
+
+/**
+ * Generates a struct definition for a thrift data type.
+ *
+ * @param tstruct The struct definition
+ */
+void t_erl_generator::generate_erl_struct_definition(ostream& out, t_struct* tstruct) {
+  indent(out) << "%% struct " << type_name(tstruct) << endl << endl;
+
+  std::stringstream buf;
+  buf << indent() << "-record(" << type_name(tstruct) << ", {";
+  string field_indent(buf.str().size(), ' ');
+
+  const vector<t_field*>& members = tstruct->get_members();
+  for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end();) {
+    generate_erl_struct_member(buf, *m_iter);
+    if (++m_iter != members.end()) {
+      buf << "," << endl << field_indent;
+    }
+  }
+  buf << "}).";
+
+  out << buf.str() << endl;
+  out << "-type " + type_name(tstruct) << "() :: #" + type_name(tstruct) + "{}." << endl << endl;
+}
+
+/**
+ * Generates the record field definition
+ */
+
+void t_erl_generator::generate_erl_struct_member(ostream& out, t_field* tmember) {
+  out << atomify(tmember->get_name());
+  if (has_default_value(tmember))
+    out << " = " << render_member_value(tmember);
+  out << " :: " << render_member_type(tmember);
+}
+
+bool t_erl_generator::has_default_value(t_field* field) {
+  t_type* type = field->get_type();
+  if (!field->get_value()) {
+    if (field->get_req() == t_field::T_REQUIRED) {
+      if (type->is_struct() || type->is_xception() || type->is_map() || type->is_set()
+          || type->is_list()) {
+        return true;
+      } else {
+        return false;
+      }
+    } else {
+      return false;
+    }
+  } else {
+    return true;
+  }
+}
+
+string t_erl_generator::render_member_value(t_field* field) {
+  if (!field->get_value()) {
+    return render_default_value(field);
+  } else {
+    return render_const_value(field->get_type(), field->get_value());
+  }
+}
+
+/**
+ * Generates the read method for a struct
+ */
+void t_erl_generator::generate_erl_struct_info(ostream& out, t_struct* tstruct) {
+  indent(out) << "struct_info(" << type_name(tstruct) << ") ->" << endl;
+  indent_up();
+  out << indent() << render_type_term(tstruct, true) << ";" << endl;
+  indent_down();
+  out << endl;
+}
+
+void t_erl_generator::generate_erl_extended_struct_info(ostream& out, t_struct* tstruct) {
+  indent(out) << "struct_info_ext(" << type_name(tstruct) << ") ->" << endl;
+  indent_up();
+  out << indent() << render_type_term(tstruct, true, true) << ";" << endl;
+  indent_down();
+  out << endl;
+}
+
+/**
+ * Generates a thrift service.
+ *
+ * @param tservice The service definition
+ */
+void t_erl_generator::generate_service(t_service* tservice) {
+  service_name_ = make_safe_for_module_name(service_name_);
+
+  string f_service_hrl_name = get_out_dir() + service_name_ + "_thrift.hrl";
+  string f_service_name = get_out_dir() + service_name_ + "_thrift.erl";
+  f_service_file_.open(f_service_name.c_str());
+  f_service_hrl_.open(f_service_hrl_name.c_str());
+
+  // Reset service text aggregating stream streams
+  f_service_.str("");
+  export_lines_.str("");
+  export_lines_first_ = true;
+
+  hrl_header(f_service_hrl_, service_name_);
+
+  if (tservice->get_extends() != NULL) {
+    f_service_hrl_ << "-include(\""
+                   << make_safe_for_module_name(tservice->get_extends()->get_name())
+                   << "_thrift.hrl\"). % inherit " << endl;
+  }
+
+  f_service_hrl_ << "-include(\"" << make_safe_for_module_name(program_name_) << "_types.hrl\")."
+                 << endl << endl;
+
+  // Generate the three main parts of the service (well, two for now in PHP)
+  generate_service_helpers(tservice); // cpiro: New Erlang Order
+
+  generate_service_interface(tservice);
+
+  // indent_down();
+
+  f_service_file_ << erl_autogen_comment() << endl << "-module(" << service_name_ << "_thrift)."
+                  << endl << "-behaviour(thrift_service)." << endl << endl << erl_imports() << endl;
+
+  f_service_file_ << "-include(\"" << make_safe_for_module_name(tservice->get_name())
+                  << "_thrift.hrl\")." << endl << endl;
+
+  f_service_file_ << "-export([" << export_lines_.str() << "])." << endl << endl;
+
+  f_service_file_ << f_service_.str();
+
+  hrl_footer(f_service_hrl_, f_service_name);
+
+  // Close service file
+  f_service_file_.close();
+  f_service_hrl_.close();
+}
+
+/**
+ * Generates helper functions for a service.
+ *
+ * @param tservice The service to generate a header definition for
+ */
+void t_erl_generator::generate_service_helpers(t_service* tservice) {
+  vector<t_function*> functions = tservice->get_functions();
+  vector<t_function*>::iterator f_iter;
+
+  //  indent(f_service_) <<
+  //  "% HELPER FUNCTIONS AND STRUCTURES" << endl << endl;
+
+  export_string("struct_info", 1);
+
+  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+    generate_erl_function_helpers(*f_iter);
+  }
+  f_service_ << "struct_info(_) -> erlang:error(function_clause)." << endl;
+}
+
+/**
+ * Generates a struct and helpers for a function.
+ *
+ * @param tfunction The function
+ */
+void t_erl_generator::generate_erl_function_helpers(t_function* tfunction) {
+  (void)tfunction;
+}
+
+/**
+ * Generates a service interface definition.
+ *
+ * @param tservice The service to generate a header definition for
+ */
+void t_erl_generator::generate_service_interface(t_service* tservice) {
+
+  export_string("function_info", 2);
+
+  vector<t_function*> functions = tservice->get_functions();
+  vector<t_function*>::iterator f_iter;
+  f_service_ << "%%% interface" << endl;
+  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+    f_service_ << indent() << "% " << function_signature(*f_iter) << endl;
+
+    generate_function_info(tservice, *f_iter);
+  }
+
+  // Inheritance - pass unknown functions to base class
+  if (tservice->get_extends() != NULL) {
+    indent(f_service_) << "function_info(Function, InfoType) ->" << endl;
+    indent_up();
+    indent(f_service_) << make_safe_for_module_name(tservice->get_extends()->get_name())
+                       << "_thrift:function_info(Function, InfoType)." << endl;
+    indent_down();
+  } else {
+    // return function_clause error for non-existent functions
+    indent(f_service_) << "function_info(_Func, _Info) -> erlang:error(function_clause)." << endl;
+  }
+
+  indent(f_service_) << endl;
+}
+
+/**
+ * Generates a function_info(FunctionName, params_type) and
+ * function_info(FunctionName, reply_type)
+ */
+void t_erl_generator::generate_function_info(t_service* tservice, t_function* tfunction) {
+  (void)tservice;
+  string name_atom = atomify(tfunction->get_name());
+
+  t_struct* xs = tfunction->get_xceptions();
+  t_struct* arg_struct = tfunction->get_arglist();
+
+  // function_info(Function, params_type):
+  indent(f_service_) << "function_info(" << name_atom << ", params_type) ->" << endl;
+  indent_up();
+
+  indent(f_service_) << render_type_term(arg_struct, true) << ";" << endl;
+
+  indent_down();
+
+  // function_info(Function, reply_type):
+  indent(f_service_) << "function_info(" << name_atom << ", reply_type) ->" << endl;
+  indent_up();
+
+  if (!tfunction->get_returntype()->is_void())
+    indent(f_service_) << render_type_term(tfunction->get_returntype(), false) << ";" << endl;
+  else if (tfunction->is_oneway())
+    indent(f_service_) << "oneway_void;" << endl;
+  else
+    indent(f_service_) << "{struct, []}"
+                       << ";" << endl;
+  indent_down();
+
+  // function_info(Function, exceptions):
+  indent(f_service_) << "function_info(" << name_atom << ", exceptions) ->" << endl;
+  indent_up();
+  indent(f_service_) << render_type_term(xs, true) << ";" << endl;
+  indent_down();
+}
+
+/**
+ * Renders a function signature of the form 'type name(args)'
+ *
+ * @param tfunction Function definition
+ * @return String of rendered function definition
+ */
+string t_erl_generator::function_signature(t_function* tfunction, string prefix) {
+  return prefix + tfunction->get_name() + "(This"
+         + capitalize(argument_list(tfunction->get_arglist())) + ")";
+}
+
+/**
+ * Add a function to the exports list
+ */
+void t_erl_generator::export_string(string name, int num) {
+  if (export_lines_first_) {
+    export_lines_first_ = false;
+  } else {
+    export_lines_ << ", ";
+  }
+  export_lines_ << name << "/" << num;
+}
+
+void t_erl_generator::export_types_function(t_function* tfunction, string prefix) {
+
+  export_types_string(prefix + tfunction->get_name(),
+                      1 // This
+                      + ((tfunction->get_arglist())->get_members()).size());
+}
+
+void t_erl_generator::export_types_string(string name, int num) {
+  if (export_types_lines_first_) {
+    export_types_lines_first_ = false;
+  } else {
+    export_types_lines_ << ", ";
+  }
+  export_types_lines_ << name << "/" << num;
+}
+
+void t_erl_generator::export_function(t_function* tfunction, string prefix) {
+
+  export_string(prefix + tfunction->get_name(),
+                1 // This
+                + ((tfunction->get_arglist())->get_members()).size());
+}
+
+/**
+ * Renders a field list
+ */
+string t_erl_generator::argument_list(t_struct* tstruct) {
+  string result = "";
+
+  const vector<t_field*>& fields = tstruct->get_members();
+  vector<t_field*>::const_iterator f_iter;
+  bool first = true;
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    if (first) {
+      first = false;
+      result += ", "; // initial comma to compensate for initial This
+    } else {
+      result += ", ";
+    }
+    result += capitalize((*f_iter)->get_name());
+  }
+  return result;
+}
+
+string t_erl_generator::type_name(t_type* ttype) {
+  string prefix = "";
+  string name = ttype->get_name();
+
+  if (ttype->is_struct() || ttype->is_xception() || ttype->is_service()) {
+    name = ttype->get_name();
+  }
+
+  return atomify(prefix + name);
+}
+
+/**
+ * Converts the parse type to a Erlang "type" (macro for int constants)
+ */
+string t_erl_generator::type_to_enum(t_type* type) {
+  type = get_true_type(type);
+
+  if (type->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
+    switch (tbase) {
+    case t_base_type::TYPE_VOID:
+      throw "NO T_VOID CONSTRUCT";
+    case t_base_type::TYPE_STRING:
+      return "?tType_STRING";
+    case t_base_type::TYPE_BOOL:
+      return "?tType_BOOL";
+    case t_base_type::TYPE_BYTE:
+      return "?tType_BYTE";
+    case t_base_type::TYPE_I16:
+      return "?tType_I16";
+    case t_base_type::TYPE_I32:
+      return "?tType_I32";
+    case t_base_type::TYPE_I64:
+      return "?tType_I64";
+    case t_base_type::TYPE_DOUBLE:
+      return "?tType_DOUBLE";
+    }
+  } else if (type->is_enum()) {
+    return "?tType_I32";
+  } else if (type->is_struct() || type->is_xception()) {
+    return "?tType_STRUCT";
+  } else if (type->is_map()) {
+    return "?tType_MAP";
+  } else if (type->is_set()) {
+    return "?tType_SET";
+  } else if (type->is_list()) {
+    return "?tType_LIST";
+  }
+
+  throw "INVALID TYPE IN type_to_enum: " + type->get_name();
+}
+
+/**
+ * Generate an Erlang term which represents a thrift type
+ */
+std::string t_erl_generator::render_type_term(t_type* type,
+                                              bool expand_structs,
+                                              bool extended_info) {
+  type = get_true_type(type);
+
+  if (type->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
+    switch (tbase) {
+    case t_base_type::TYPE_VOID:
+      throw "NO T_VOID CONSTRUCT";
+    case t_base_type::TYPE_STRING:
+      return "string";
+    case t_base_type::TYPE_BOOL:
+      return "bool";
+    case t_base_type::TYPE_BYTE:
+      return "byte";
+    case t_base_type::TYPE_I16:
+      return "i16";
+    case t_base_type::TYPE_I32:
+      return "i32";
+    case t_base_type::TYPE_I64:
+      return "i64";
+    case t_base_type::TYPE_DOUBLE:
+      return "double";
+    }
+  } else if (type->is_enum()) {
+    return "i32";
+  } else if (type->is_struct() || type->is_xception()) {
+    if (expand_structs) {
+
+      std::stringstream buf;
+      buf << "{struct, [";
+      string field_indent(buf.str().size(), ' ');
+
+      t_struct::members_type const& fields = static_cast<t_struct*>(type)->get_members();
+      t_struct::members_type::const_iterator i, end = fields.end();
+      for (i = fields.begin(); i != end;) {
+        t_struct::members_type::value_type member = *i;
+        int32_t key = member->get_key();
+        string type = render_type_term(member->get_type(), false, false); // recursive call
+
+        if (!extended_info) {
+          // Convert to format: {struct, [{Fid, Type}|...]}
+          buf << "{" << key << ", " << type << "}";
+        } else {
+          // Convert to format: {struct, [{Fid, Req, Type, Name, Def}|...]}
+          string name = member->get_name();
+          string value = render_member_value(member);
+          string requiredness = render_member_requiredness(member);
+          buf << "{" << key << ", " << requiredness << ", " << type << ", " << atomify(name) << ", "
+              << value << "}";
+        }
+
+        if (++i != end) {
+          buf << "," << endl << field_indent;
+        }
+      }
+
+      buf << "]}" << endl;
+      return buf.str();
+    } else {
+      return "{struct, {" + atomify(type_module(type)) + ", " + type_name(type) + "}}";
+    }
+  } else if (type->is_map()) {
+    // {map, KeyType, ValType}
+    t_type* key_type = ((t_map*)type)->get_key_type();
+    t_type* val_type = ((t_map*)type)->get_val_type();
+
+    return "{map, " + render_type_term(key_type, false) + ", " + render_type_term(val_type, false)
+           + "}";
+
+  } else if (type->is_set()) {
+    t_type* elem_type = ((t_set*)type)->get_elem_type();
+
+    return "{set, " + render_type_term(elem_type, false) + "}";
+
+  } else if (type->is_list()) {
+    t_type* elem_type = ((t_list*)type)->get_elem_type();
+
+    return "{list, " + render_type_term(elem_type, false) + "}";
+  }
+
+  throw "INVALID TYPE IN type_to_enum: " + type->get_name();
+}
+
+std::string t_erl_generator::type_module(t_type* ttype) {
+  return make_safe_for_module_name(ttype->get_program()->get_name()) + "_types";
+}
+
+THRIFT_REGISTER_GENERATOR(
+    erl,
+    "Erlang",
+    "    legacynames: Output files retain naming conventions of Thrift 0.9.1 and earlier.\n"
+    "    maps:        Generate maps instead of dicts.\n"
+    "    otp16:       Generate non-namespaced dict and set instead of dict:dict and sets:set.\n")

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.cc
----------------------------------------------------------------------
diff --git a/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.cc b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.cc
new file mode 100644
index 0000000..e7760d7
--- /dev/null
+++ b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.cc
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "t_generator.h"
+using namespace std;
+
+/**
+ * Top level program generation function. Calls the generator subclass methods
+ * for preparing file streams etc. then iterates over all the parts of the
+ * program to perform the correct actions.
+ *
+ * @param program The thrift program to compile into C++ source
+ */
+void t_generator::generate_program() {
+  // Initialize the generator
+  init_generator();
+
+  // Generate enums
+  vector<t_enum*> enums = program_->get_enums();
+  vector<t_enum*>::iterator en_iter;
+  for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) {
+    generate_enum(*en_iter);
+  }
+
+  // Generate typedefs
+  vector<t_typedef*> typedefs = program_->get_typedefs();
+  vector<t_typedef*>::iterator td_iter;
+  for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) {
+    generate_typedef(*td_iter);
+  }
+
+  // Generate structs, exceptions, and unions in declared order
+  vector<t_struct*> objects = program_->get_objects();
+
+  vector<t_struct*>::iterator o_iter;
+  for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) {
+    generate_forward_declaration(*o_iter);
+  }
+  for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) {
+    if ((*o_iter)->is_xception()) {
+      generate_xception(*o_iter);
+    } else {
+      generate_struct(*o_iter);
+    }
+  }
+
+  // Generate constants
+  vector<t_const*> consts = program_->get_consts();
+  generate_consts(consts);
+
+  // Generate services
+  vector<t_service*> services = program_->get_services();
+  vector<t_service*>::iterator sv_iter;
+  for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) {
+    service_name_ = get_service_name(*sv_iter);
+    generate_service(*sv_iter);
+  }
+
+  // Close the generator
+  close_generator();
+}
+
+string t_generator::escape_string(const string& in) const {
+  string result = "";
+  for (string::const_iterator it = in.begin(); it < in.end(); it++) {
+    std::map<char, std::string>::const_iterator res = escape_.find(*it);
+    if (res != escape_.end()) {
+      result.append(res->second);
+    } else {
+      result.push_back(*it);
+    }
+  }
+  return result;
+}
+
+void t_generator::generate_consts(vector<t_const*> consts) {
+  vector<t_const*>::iterator c_iter;
+  for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
+    generate_const(*c_iter);
+  }
+}
+
+void t_generator::generate_docstring_comment(ostream& out,
+                                             const string& comment_start,
+                                             const string& line_prefix,
+                                             const string& contents,
+                                             const string& comment_end) {
+  if (comment_start != "")
+    indent(out) << comment_start;
+  stringstream docs(contents, ios_base::in);
+  while (!(docs.eof() || docs.fail())) {
+    char line[1024];
+    docs.getline(line, 1024);
+
+    // Just prnt a newline when the line & prefix are empty.
+    if (strlen(line) == 0 && line_prefix == "" && !docs.eof()) {
+      out << std::endl;
+    } else if (strlen(line) > 0 || !docs.eof()) { // skip the empty last line
+      indent(out) << line_prefix << line << std::endl;
+    }
+  }
+  if (comment_end != "")
+    indent(out) << comment_end;
+}
+
+void t_generator_registry::register_generator(t_generator_factory* factory) {
+  gen_map_t& the_map = get_generator_map();
+  if (the_map.find(factory->get_short_name()) != the_map.end()) {
+    failure("Duplicate generators for language \"%s\"!\n", factory->get_short_name().c_str());
+  }
+  the_map[factory->get_short_name()] = factory;
+}
+
+t_generator* t_generator_registry::get_generator(t_program* program, const string& options) {
+  string::size_type colon = options.find(':');
+  string language = options.substr(0, colon);
+
+  map<string, string> parsed_options;
+  if (colon != string::npos) {
+    string::size_type pos = colon + 1;
+    while (pos != string::npos && pos < options.size()) {
+      string::size_type next_pos = options.find(',', pos);
+      string option = options.substr(pos, next_pos - pos);
+      pos = ((next_pos == string::npos) ? next_pos : next_pos + 1);
+
+      string::size_type separator = option.find('=');
+      string key, value;
+      if (separator == string::npos) {
+        key = option;
+        value = "";
+      } else {
+        key = option.substr(0, separator);
+        value = option.substr(separator + 1);
+      }
+
+      parsed_options[key] = value;
+    }
+  }
+
+  gen_map_t& the_map = get_generator_map();
+  gen_map_t::iterator iter = the_map.find(language);
+
+  if (iter == the_map.end()) {
+    return NULL;
+  }
+
+  return iter->second->get_generator(program, parsed_options, options);
+}
+
+t_generator_registry::gen_map_t& t_generator_registry::get_generator_map() {
+  // http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
+  static gen_map_t* the_map = new gen_map_t();
+  return *the_map;
+}
+
+t_generator_factory::t_generator_factory(const std::string& short_name,
+                                         const std::string& long_name,
+                                         const std::string& documentation)
+  : short_name_(short_name), long_name_(long_name), documentation_(documentation) {
+  t_generator_registry::register_generator(this);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.h
----------------------------------------------------------------------
diff --git a/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.h b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.h
new file mode 100644
index 0000000..99d878a
--- /dev/null
+++ b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator.h
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef T_GENERATOR_H
+#define T_GENERATOR_H
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "parse/t_program.h"
+#include "globals.h"
+#include "t_generator_registry.h"
+
+/**
+ * Base class for a thrift code generator. This class defines the basic
+ * routines for code generation and contains the top level method that
+ * dispatches code generation across various components.
+ *
+ */
+class t_generator {
+public:
+  t_generator(t_program* program) {
+    tmp_ = 0;
+    indent_ = 0;
+    program_ = program;
+    program_name_ = get_program_name(program);
+    escape_['\n'] = "\\n";
+    escape_['\r'] = "\\r";
+    escape_['\t'] = "\\t";
+    escape_['"'] = "\\\"";
+    escape_['\\'] = "\\\\";
+  }
+
+  virtual ~t_generator() {}
+
+  /**
+   * Framework generator method that iterates over all the parts of a program
+   * and performs general actions. This is implemented by the base class and
+   * should not normally be overwritten in the subclasses.
+   */
+  virtual void generate_program();
+
+  const t_program* get_program() const { return program_; }
+
+  void generate_docstring_comment(std::ostream& out,
+                                  const std::string& comment_start,
+                                  const std::string& line_prefix,
+                                  const std::string& contents,
+                                  const std::string& comment_end);
+
+  /**
+   * check whether sub-namespace declaraction is used by generator.
+   * e.g. allow
+   * namespace py.twisted bar
+   * to specify namespace to use when -gen py:twisted is specified.
+   * Will be called with subnamespace, i.e. is_valid_namespace("twisted")
+   * will be called for the above example.
+   */
+  static bool is_valid_namespace(const std::string& sub_namespace) {
+    (void)sub_namespace;
+    return false;
+  }
+
+  /**
+   * Escape string to use one in generated sources.
+   */
+  virtual std::string escape_string(const std::string& in) const;
+
+  std::string get_escaped_string(t_const_value* constval) {
+    return escape_string(constval->get_string());
+  }
+
+protected:
+  /**
+   * Optional methods that may be imlemented by subclasses to take necessary
+   * steps at the beginning or end of code generation.
+   */
+
+  virtual void init_generator() {}
+  virtual void close_generator() {}
+
+  virtual void generate_consts(std::vector<t_const*> consts);
+
+  /**
+   * Pure virtual methods implemented by the generator subclasses.
+   */
+
+  virtual void generate_typedef(t_typedef* ttypedef) = 0;
+  virtual void generate_enum(t_enum* tenum) = 0;
+  virtual void generate_const(t_const* tconst) { (void)tconst; }
+  virtual void generate_struct(t_struct* tstruct) = 0;
+  virtual void generate_service(t_service* tservice) = 0;
+  virtual void generate_forward_declaration(t_struct*) {}
+  virtual void generate_xception(t_struct* txception) {
+    // By default exceptions are the same as structs
+    generate_struct(txception);
+  }
+
+  /**
+   * Method to get the program name, may be overridden
+   */
+  virtual std::string get_program_name(t_program* tprogram) { return tprogram->get_name(); }
+
+  /**
+   * Method to get the service name, may be overridden
+   */
+  virtual std::string get_service_name(t_service* tservice) { return tservice->get_name(); }
+
+  /**
+   * Get the current output directory
+   */
+  virtual std::string get_out_dir() const {
+    if (program_->is_out_path_absolute()) {
+      return program_->get_out_path() + "/";
+    }
+
+    return program_->get_out_path() + out_dir_base_ + "/";
+  }
+
+  /**
+   * Creates a unique temporary variable name, which is just "name" with a
+   * number appended to it (i.e. name35)
+   */
+  std::string tmp(std::string name) {
+    std::ostringstream out;
+    out << name << tmp_++;
+    return out.str();
+  }
+
+  /**
+   * Indentation level modifiers
+   */
+
+  void indent_up() { ++indent_; }
+
+  void indent_down() { --indent_; }
+
+  /**
+   * Indentation print function
+   */
+  std::string indent() {
+    std::string ind = "";
+    int i;
+    for (i = 0; i < indent_; ++i) {
+      ind += "  ";
+    }
+    return ind;
+  }
+
+  /**
+   * Indentation utility wrapper
+   */
+  std::ostream& indent(std::ostream& os) { return os << indent(); }
+
+  /**
+   * Capitalization helpers
+   */
+  std::string capitalize(std::string in) {
+    in[0] = toupper(in[0]);
+    return in;
+  }
+  std::string decapitalize(std::string in) {
+    in[0] = tolower(in[0]);
+    return in;
+  }
+  static std::string lowercase(std::string in) {
+    for (size_t i = 0; i < in.size(); ++i) {
+      in[i] = tolower(in[i]);
+    }
+    return in;
+  }
+  static std::string uppercase(std::string in) {
+    for (size_t i = 0; i < in.size(); ++i) {
+      in[i] = toupper(in[i]);
+    }
+    return in;
+  }
+  /**
+   * Transforms a camel case string to an equivalent one separated by underscores
+   * e.g. aMultiWord -> a_multi_word
+   *      someName   -> some_name
+   *      CamelCase  -> camel_case
+   *      name       -> name
+   *      Name       -> name
+   */
+  std::string underscore(std::string in) {
+    in[0] = tolower(in[0]);
+    for (size_t i = 1; i < in.size(); ++i) {
+      if (isupper(in[i])) {
+        in[i] = tolower(in[i]);
+        in.insert(i, "_");
+      }
+    }
+    return in;
+  }
+  /**
+    * Transforms a string with words separated by underscores to a camel case equivalent
+    * e.g. a_multi_word -> aMultiWord
+    *      some_name    ->  someName
+    *      name         ->  name
+    */
+  std::string camelcase(std::string in) {
+    std::ostringstream out;
+    bool underscore = false;
+
+    for (size_t i = 0; i < in.size(); i++) {
+      if (in[i] == '_') {
+        underscore = true;
+        continue;
+      }
+      if (underscore) {
+        out << (char)toupper(in[i]);
+        underscore = false;
+        continue;
+      }
+      out << in[i];
+    }
+
+    return out.str();
+  }
+
+public:
+  /**
+   * Get the true type behind a series of typedefs.
+   */
+  static t_type* get_true_type(t_type* type) { return type->get_true_type(); }
+
+protected:
+  /**
+   * The program being generated
+   */
+  t_program* program_;
+
+  /**
+   * Quick accessor for formatted program name that is currently being
+   * generated.
+   */
+  std::string program_name_;
+
+  /**
+   * Quick accessor for formatted service name that is currently being
+   * generated.
+   */
+  std::string service_name_;
+
+  /**
+   * Output type-specifc directory name ("gen-*")
+   */
+  std::string out_dir_base_;
+
+  /**
+   * Map of characters to escape in string literals.
+   */
+  std::map<char, std::string> escape_;
+
+private:
+  /**
+   * Current code indentation level
+   */
+  int indent_;
+
+  /**
+   * Temporary variable counter, for making unique variable names
+   */
+  int tmp_;
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d709f67d/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator_registry.h
----------------------------------------------------------------------
diff --git a/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator_registry.h b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator_registry.h
new file mode 100644
index 0000000..a852385
--- /dev/null
+++ b/depends/thirdparty/thrift/compiler/cpp/src/generate/t_generator_registry.h
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef T_GENERATOR_REGISTRY_H
+#define T_GENERATOR_REGISTRY_H
+
+class t_generator;
+
+/**
+ * A factory for producing generator classes of a particular language.
+ *
+ * This class is also responsible for:
+ *  - Registering itself with the generator registry.
+ *  - Providing documentation for the generators it produces.
+ */
+class t_generator_factory {
+public:
+  t_generator_factory(const std::string& short_name,
+                      const std::string& long_name,
+                      const std::string& documentation);
+
+  virtual ~t_generator_factory() {}
+
+  virtual t_generator* get_generator(
+      // The program to generate.
+      t_program* program,
+      // Note: parsed_options will not exist beyond the call to get_generator.
+      const std::map<std::string, std::string>& parsed_options,
+      // Note: option_string might not exist beyond the call to get_generator.
+      const std::string& option_string) = 0;
+
+  virtual bool is_valid_namespace(const std::string& sub_namespace) = 0;
+
+  std::string get_short_name() { return short_name_; }
+  std::string get_long_name() { return long_name_; }
+  std::string get_documentation() { return documentation_; }
+
+private:
+  std::string short_name_;
+  std::string long_name_;
+  std::string documentation_;
+};
+
+template <typename generator>
+class t_generator_factory_impl : public t_generator_factory {
+public:
+  t_generator_factory_impl(const std::string& short_name,
+                           const std::string& long_name,
+                           const std::string& documentation)
+    : t_generator_factory(short_name, long_name, documentation) {}
+
+  virtual t_generator* get_generator(t_program* program,
+                                     const std::map<std::string, std::string>& parsed_options,
+                                     const std::string& option_string) {
+    return new generator(program, parsed_options, option_string);
+  }
+
+  virtual bool is_valid_namespace(const std::string& sub_namespace) {
+    return generator::is_valid_namespace(sub_namespace);
+  }
+};
+
+class t_generator_registry {
+public:
+  static void register_generator(t_generator_factory* factory);
+
+  static t_generator* get_generator(t_program* program, const std::string& options);
+
+  typedef std::map<std::string, t_generator_factory*> gen_map_t;
+  static gen_map_t& get_generator_map();
+
+private:
+  t_generator_registry();
+  t_generator_registry(const t_generator_registry&);
+};
+
+#define THRIFT_REGISTER_GENERATOR(language, long_name, doc)                                        \
+  class t_##language##_generator_factory_impl                                                      \
+      : public t_generator_factory_impl<t_##language##_generator> {                                \
+  public:                                                                                          \
+    t_##language##_generator_factory_impl()                                                        \
+      : t_generator_factory_impl<t_##language##_generator>(#language, long_name, doc) {}           \
+  };                                                                                               \
+  static t_##language##_generator_factory_impl _registerer;
+
+#endif


Mime
View raw message