You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by hc...@apache.org on 2014/11/18 11:34:20 UTC
[28/37] thrift git commit: Revert "THRIFT-2729: C++ - .clang-format
created and applied"
http://git-wip-us.apache.org/repos/asf/thrift/blob/240120c8/compiler/cpp/src/generate/t_go_generator.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc
index 7610da4..adc4221 100644
--- a/compiler/cpp/src/generate/t_go_generator.cc
+++ b/compiler/cpp/src/generate/t_go_generator.cc
@@ -46,7 +46,7 @@ using std::string;
using std::stringstream;
using std::vector;
-static const string endl = "\n"; // avoid ostream << std::endl flushes
+static const string endl = "\n"; // avoid ostream << std::endl flushes
/**
* A helper for automatically formatting the emitted Go code from the Thrift
@@ -57,7 +57,7 @@ static const string endl = "\n"; // avoid ostream << std::endl flushes
* - false, if the formatting process failed, which means the basic output was
* still generated.
*/
-bool format_go_output(const string& file_path);
+bool format_go_output(const string &file_path);
const string default_thrift_import = "git.apache.org/thrift.git/lib/go/thrift";
static std::string package_flag;
@@ -65,634 +65,646 @@ static std::string package_flag;
/**
* Go code generator.
*/
-class t_go_generator : public t_generator {
+class t_go_generator : public t_generator
+{
public:
- t_go_generator(t_program* program,
- const std::map<std::string, std::string>& parsed_options,
- const std::string& option_string)
- : t_generator(program) {
- (void)option_string;
- std::map<std::string, std::string>::const_iterator iter;
- out_dir_base_ = "gen-go";
- gen_thrift_import_ = default_thrift_import;
-
- iter = parsed_options.find("package_prefix");
-
- if (iter != parsed_options.end()) {
- gen_package_prefix_ = (iter->second);
- }
-
- iter = parsed_options.find("thrift_import");
-
- if (iter != parsed_options.end()) {
- gen_thrift_import_ = (iter->second);
- }
-
- iter = parsed_options.find("package");
-
- if (iter != parsed_options.end()) {
- package_flag = (iter->second);
- }
- }
-
- /**
- * 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);
-
- std::string render_const_value(t_type* type, t_const_value* value, const string& name);
-
- /**
- * Struct generation code
- */
-
- void generate_go_struct(t_struct* tstruct, bool is_exception);
- void generate_go_struct_definition(std::ofstream& out,
- t_struct* tstruct,
- bool is_xception = false,
- bool is_result = false,
- bool is_args = false);
- void generate_go_struct_initializer(std::ofstream& out,
- t_struct* tstruct,
- bool is_args_or_result = false);
- void generate_isset_helpers(std::ofstream& out,
- t_struct* tstruct,
- const string& tstruct_name,
- bool is_result = false);
- void generate_go_struct_reader(std::ofstream& out,
- t_struct* tstruct,
- const string& tstruct_name,
- bool is_result = false);
- void generate_go_struct_writer(std::ofstream& out,
- t_struct* tstruct,
- const string& tstruct_name,
- bool is_result = false);
- void generate_go_function_helpers(t_function* tfunction);
- void get_publicized_name_and_def_value(t_field* tfield,
- string* OUT_pub_name,
- t_const_value** OUT_def_value) const;
-
- /**
- * Service-level generation functions
- */
-
- void generate_service_helpers(t_service* tservice);
- void generate_service_interface(t_service* tservice);
- void generate_service_client(t_service* tservice);
- void generate_service_remote(t_service* tservice);
- void generate_service_server(t_service* tservice);
- void generate_process_function(t_service* tservice, t_function* tfunction);
-
- /**
- * Serialization constructs
- */
-
- void generate_deserialize_field(std::ofstream& out,
- t_field* tfield,
- bool declare,
- std::string prefix = "",
- bool inclass = false,
- bool coerceData = false,
- bool inkey = false,
- bool in_container = false);
-
- void generate_deserialize_struct(std::ofstream& out,
- t_struct* tstruct,
- bool is_pointer_field,
- bool declare,
- std::string prefix = "");
+ t_go_generator(
+ t_program* program,
+ const std::map<std::string, std::string>& parsed_options,
+ const std::string& option_string)
+ : t_generator(program) {
+ (void) option_string;
+ std::map<std::string, std::string>::const_iterator iter;
+ out_dir_base_ = "gen-go";
+ gen_thrift_import_ = default_thrift_import;
+
+ iter = parsed_options.find("package_prefix");
+
+ if (iter != parsed_options.end()) {
+ gen_package_prefix_ = (iter->second);
+ }
- void generate_deserialize_container(std::ofstream& out,
- t_type* ttype,
- bool pointer_field,
- bool declare,
- std::string prefix = "");
-
- void generate_deserialize_set_element(std::ofstream& out,
- t_set* tset,
- bool declare,
- std::string prefix = "");
-
- void generate_deserialize_map_element(std::ofstream& out,
- t_map* tmap,
- bool declare,
- std::string prefix = "");
-
- void generate_deserialize_list_element(std::ofstream& out,
- t_list* tlist,
- bool declare,
- std::string prefix = "");
-
- void generate_serialize_field(std::ofstream& out,
- t_field* tfield,
- std::string prefix = "",
- bool inkey = false);
-
- void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-
- void generate_serialize_container(std::ofstream& out,
- t_type* ttype,
- bool pointer_field,
- std::string prefix = "");
-
- void generate_serialize_map_element(std::ofstream& out,
- t_map* tmap,
- std::string kiter,
- std::string viter);
-
- void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
-
- void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
-
- void generate_go_docstring(std::ofstream& out, t_struct* tstruct);
-
- void generate_go_docstring(std::ofstream& out, t_function* tfunction);
-
- void generate_go_docstring(std::ofstream& out,
- t_doc* tdoc,
- t_struct* tstruct,
- const char* subheader);
-
- void generate_go_docstring(std::ofstream& out, t_doc* tdoc);
-
- /**
- * Helper rendering functions
- */
-
- std::string go_autogen_comment();
- std::string go_package();
- std::string go_imports_begin();
- std::string go_imports_end();
- std::string render_includes();
- std::string render_import_protection();
- std::string render_fastbinary_includes();
- std::string declare_argument(t_field* tfield);
- std::string render_field_initial_value(t_field* tfield, const string& name, bool optional_field);
- std::string type_name(t_type* ttype);
- std::string function_signature(t_function* tfunction, std::string prefix = "");
- std::string function_signature_if(t_function* tfunction,
- std::string prefix = "",
- bool addError = false);
- std::string argument_list(t_struct* tstruct);
- std::string type_to_enum(t_type* ttype);
- std::string type_to_go_type(t_type* ttype, bool is_container_value = false);
- std::string type_to_go_type_with_opt(t_type* ttype,
- bool optional_field,
- bool is_container_value = false);
- std::string type_to_go_key_type(t_type* ttype);
- std::string type_to_spec_args(t_type* ttype);
+ iter = parsed_options.find("thrift_import");
- static std::string get_real_go_module(const t_program* program) {
+ if (iter != parsed_options.end()) {
+ gen_thrift_import_ = (iter->second);
+ }
- if (!package_flag.empty()) {
- return package_flag;
- }
- std::string real_module = program->get_namespace("go");
- if (!real_module.empty()) {
- return real_module;
+ iter = parsed_options.find("package");
+
+ if (iter != parsed_options.end()) {
+ package_flag = (iter->second);
+ }
}
- return lowercase(program->get_name());
- }
+ /**
+ * 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);
+
+ std::string render_const_value(t_type* type, t_const_value* value, const string& name);
+
+ /**
+ * Struct generation code
+ */
+
+ void generate_go_struct(t_struct* tstruct, bool is_exception);
+ void generate_go_struct_definition(std::ofstream& out, t_struct* tstruct, bool is_xception = false, bool is_result = false, bool is_args = false);
+ void generate_go_struct_initializer(std::ofstream& out, t_struct* tstruct, bool is_args_or_result = false);
+ void generate_isset_helpers(std::ofstream& out, t_struct* tstruct, const string& tstruct_name, bool is_result = false);
+ void generate_go_struct_reader(std::ofstream& out, t_struct* tstruct, const string& tstruct_name, bool is_result = false);
+ void generate_go_struct_writer(std::ofstream& out, t_struct* tstruct, const string& tstruct_name, bool is_result = false);
+ void generate_go_function_helpers(t_function* tfunction);
+ void get_publicized_name_and_def_value(t_field* tfield,
+ string* OUT_pub_name,
+ t_const_value** OUT_def_value) const;
+
+ /**
+ * Service-level generation functions
+ */
+
+ void generate_service_helpers(t_service* tservice);
+ void generate_service_interface(t_service* tservice);
+ void generate_service_client(t_service* tservice);
+ void generate_service_remote(t_service* tservice);
+ void generate_service_server(t_service* tservice);
+ void generate_process_function(t_service* tservice, t_function* tfunction);
+
+ /**
+ * Serialization constructs
+ */
+
+ void generate_deserialize_field(std::ofstream &out,
+ t_field* tfield,
+ bool declare,
+ std::string prefix = "",
+ bool inclass = false,
+ bool coerceData = false,
+ bool inkey = false,
+ bool in_container = false);
+
+ void generate_deserialize_struct(std::ofstream &out,
+ t_struct* tstruct,
+ bool is_pointer_field,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_container(std::ofstream &out,
+ t_type* ttype,
+ bool pointer_field,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_set_element(std::ofstream &out,
+ t_set* tset,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_map_element(std::ofstream &out,
+ t_map* tmap,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_deserialize_list_element(std::ofstream &out,
+ t_list* tlist,
+ bool declare,
+ std::string prefix = "");
+
+ void generate_serialize_field(std::ofstream &out,
+ t_field* tfield,
+ std::string prefix = "",
+ bool inkey = false);
+
+ void generate_serialize_struct(std::ofstream &out,
+ t_struct* tstruct,
+ std::string prefix = "");
+
+ void generate_serialize_container(std::ofstream &out,
+ t_type* ttype,
+ bool pointer_field,
+ std::string prefix = "");
+
+ void generate_serialize_map_element(std::ofstream &out,
+ t_map* tmap,
+ std::string kiter,
+ std::string viter);
+
+ void generate_serialize_set_element(std::ofstream &out,
+ t_set* tmap,
+ std::string iter);
+
+ void generate_serialize_list_element(std::ofstream &out,
+ t_list* tlist,
+ std::string iter);
+
+ void generate_go_docstring(std::ofstream& out,
+ t_struct* tstruct);
+
+ void generate_go_docstring(std::ofstream& out,
+ t_function* tfunction);
+
+ void generate_go_docstring(std::ofstream& out,
+ t_doc* tdoc,
+ t_struct* tstruct,
+ const char* subheader);
+
+ void generate_go_docstring(std::ofstream& out,
+ t_doc* tdoc);
+
+ /**
+ * Helper rendering functions
+ */
+
+ std::string go_autogen_comment();
+ std::string go_package();
+ std::string go_imports_begin();
+ std::string go_imports_end();
+ std::string render_includes();
+ std::string render_import_protection();
+ std::string render_fastbinary_includes();
+ std::string declare_argument(t_field* tfield);
+ std::string render_field_initial_value(t_field* tfield,
+ const string& name,
+ bool optional_field);
+ std::string type_name(t_type* ttype);
+ std::string function_signature(t_function* tfunction, std::string prefix = "");
+ std::string function_signature_if(t_function* tfunction, std::string prefix = "", bool addError = false);
+ std::string argument_list(t_struct* tstruct);
+ std::string type_to_enum(t_type* ttype);
+ std::string type_to_go_type(t_type* ttype, bool is_container_value = false);
+ std::string type_to_go_type_with_opt(t_type* ttype, bool optional_field, bool is_container_value = false);
+ std::string type_to_go_key_type(t_type* ttype);
+ std::string type_to_spec_args(t_type* ttype);
+
+ static std::string get_real_go_module(const t_program* program) {
+
+ if (!package_flag.empty()) {
+ return package_flag;
+ }
+ std::string real_module = program->get_namespace("go");
+ if (!real_module.empty()) {
+ return real_module;
+ }
+
+ return lowercase(program->get_name());
+ }
private:
- std::string gen_package_prefix_;
- std::string gen_thrift_import_;
-
- /**
- * File streams
- */
-
- std::ofstream f_types_;
- std::string f_types_name_;
- std::ofstream f_consts_;
- std::string f_consts_name_;
- std::stringstream f_const_values_;
- std::ofstream f_service_;
-
- std::string package_name_;
- std::string package_dir_;
-
- static std::string publicize(const std::string& value, bool is_args_or_result = false);
- static std::string new_prefix(const std::string& value);
- static std::string privatize(const std::string& value);
- static std::string variable_name_to_go_name(const std::string& value);
- static bool is_pointer_field(t_field* tfield, bool in_container = false);
- static bool omit_initialization(t_field* tfield);
+
+ std::string gen_package_prefix_;
+ std::string gen_thrift_import_;
+
+ /**
+ * File streams
+ */
+
+ std::ofstream f_types_;
+ std::string f_types_name_;
+ std::ofstream f_consts_;
+ std::string f_consts_name_;
+ std::stringstream f_const_values_;
+ std::ofstream f_service_;
+
+ std::string package_name_;
+ std::string package_dir_;
+
+ static std::string publicize(const std::string& value, bool is_args_or_result = false);
+ static std::string new_prefix(const std::string& value);
+ static std::string privatize(const std::string& value);
+ static std::string variable_name_to_go_name(const std::string& value);
+ static bool is_pointer_field(t_field* tfield, bool in_container = false);
+ static bool omit_initialization(t_field* tfield);
};
-// returns true if field initialization can be omitted since it has corresponding go type zero value
-// or default value is not set
+//returns true if field initialization can be omitted since it has corresponding go type zero value
+//or default value is not set
bool t_go_generator::omit_initialization(t_field* tfield) {
- t_const_value* value = tfield->get_value();
- if (!value) {
- return true;
- }
- t_type* type = tfield->get_type()->get_true_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 "";
-
- case t_base_type::TYPE_STRING:
- if (((t_base_type*)type)->is_binary()) {
- //[]byte are always inline
- return false;
- }
- // strings are pointers if has no default
- return value->get_string().empty();
-
- case t_base_type::TYPE_BOOL:
- 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 value->get_integer() == 0;
- case t_base_type::TYPE_DOUBLE:
- if (value->get_type() == t_const_value::CV_INTEGER) {
- return value->get_integer() == 0;
- } else {
- return value->get_double() == 0.;
- }
- }
- }
- return false;
-}
-
-// Returns true if the type need a reference if used as optional without default
-static bool type_need_reference(t_type* type) {
- type = type->get_true_type();
- if (type->is_map() || type->is_set() || type->is_list() || type->is_struct()
- || type->is_xception() || (type->is_string() && ((t_base_type*)type)->is_binary())) {
- return false;
- }
- return true;
+ t_const_value* value = tfield->get_value();
+ if (!value) {
+ return true;
+ }
+ t_type* type = tfield->get_type()->get_true_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 "";
+
+ case t_base_type::TYPE_STRING:
+ if (((t_base_type*)type)->is_binary()) {
+ //[]byte are always inline
+ return false;
+ }
+ //strings are pointers if has no default
+ return value->get_string().empty();
+
+ case t_base_type::TYPE_BOOL:
+ 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 value->get_integer()==0;
+ case t_base_type::TYPE_DOUBLE:
+ if (value->get_type() == t_const_value::CV_INTEGER) {
+ return value->get_integer()==0;
+ } else {
+ return value->get_double()==0.;
+ }
+ }
+ }
+ return false;
}
-// returns false if field could not use comparison to default value as !IsSet*
+//Returns true if the type need a reference if used as optional without default
+static bool type_need_reference(t_type* type) {
+ type = type->get_true_type();
+ if( type->is_map()
+ || type->is_set()
+ || type->is_list()
+ || type->is_struct()
+ || type->is_xception()
+ || (type->is_string() && ((t_base_type*)type)->is_binary() )) {
+ return false;
+ }
+ return true;
+}
+
+//returns false if field could not use comparison to default value as !IsSet*
bool t_go_generator::is_pointer_field(t_field* tfield, bool in_container_value) {
- (void)in_container_value;
- if (tfield->annotations_.count("cpp.ref") != 0) {
- return true;
- }
- t_type* type = tfield->get_type()->get_true_type();
- // Structs in containers are pointers
- if (type->is_struct() || type->is_xception()) {
- return true;
- }
- if (!(tfield->get_req() == t_field::T_OPTIONAL)) {
- return false;
- }
-
- bool has_default = tfield->get_value();
- 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 "";
-
- case t_base_type::TYPE_STRING:
- if (((t_base_type*)type)->is_binary()) {
- //[]byte are always inline
- return false;
- }
- // strings are pointers if has no default
- return !has_default;
-
- case t_base_type::TYPE_BOOL:
- case t_base_type::TYPE_BYTE:
- case t_base_type::TYPE_I16:
- case t_base_type::TYPE_I32:
- case t_base_type::TYPE_I64:
- case t_base_type::TYPE_DOUBLE:
- return !has_default;
- }
- } else if (type->is_enum()) {
- return !has_default;
- } else if (type->is_struct() || type->is_xception()) {
- return true;
- } else if (type->is_map()) {
- return has_default;
- } else if (type->is_set()) {
- return has_default;
- } else if (type->is_list()) {
- return has_default;
- } else if (type->is_typedef()) {
- return has_default;
- }
-
- throw "INVALID TYPE IN type_to_go_type: " + type->get_name();
+ (void) in_container_value;
+ if (tfield->annotations_.count("cpp.ref")!=0) {
+ return true;
+ }
+ t_type* type = tfield->get_type()->get_true_type();
+ //Structs in containers are pointers
+ if (type->is_struct() || type->is_xception()) {
+ return true;
+ }
+ if (!(tfield->get_req() == t_field::T_OPTIONAL)) {
+ return false;
+ }
+
+ bool has_default = tfield->get_value();
+ 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 "";
+
+ case t_base_type::TYPE_STRING:
+ if (((t_base_type*)type)->is_binary()) {
+ //[]byte are always inline
+ return false;
+ }
+ //strings are pointers if has no default
+ return !has_default;
+
+ case t_base_type::TYPE_BOOL:
+ case t_base_type::TYPE_BYTE:
+ case t_base_type::TYPE_I16:
+ case t_base_type::TYPE_I32:
+ case t_base_type::TYPE_I64:
+ case t_base_type::TYPE_DOUBLE:
+ return !has_default;
+ }
+ } else if (type->is_enum()) {
+ return !has_default;
+ } else if (type->is_struct() || type->is_xception()) {
+ return true;
+ } else if (type->is_map()) {
+ return has_default;
+ } else if (type->is_set()) {
+ return has_default;
+ } else if (type->is_list()) {
+ return has_default;
+ } else if (type->is_typedef()) {
+ return has_default;
+ }
+
+ throw "INVALID TYPE IN type_to_go_type: " + type->get_name();
}
-std::string t_go_generator::publicize(const std::string& value, bool is_args_or_result) {
- if (value.size() <= 0) {
- return value;
- }
+std::string t_go_generator::publicize(const std::string& value, bool is_args_or_result)
+{
+ if (value.size() <= 0) {
+ return value;
+ }
- std::string value2(value), prefix;
+ std::string value2(value), prefix;
- string::size_type dot_pos = value.rfind('.');
- if (dot_pos != string::npos) {
- prefix = value.substr(0, dot_pos + 1) + prefix;
- value2 = value.substr(dot_pos + 1);
- }
+ string::size_type dot_pos = value.rfind('.');
+ if (dot_pos != string::npos) {
+ prefix = value.substr(0, dot_pos + 1) + prefix;
+ value2 = value.substr(dot_pos + 1);
+ }
- if (!isupper(value2[0])) {
- value2[0] = toupper(value2[0]);
- }
+ if (!isupper(value2[0])) {
+ value2[0] = toupper(value2[0]);
+ }
- // as long as we are changing things, let's change _ followed by lowercase to capital
- for (string::size_type i = 1; i < value2.size() - 1; ++i) {
- if (value2[i] == '_' && islower(value2[i + 1])) {
- value2.replace(i, 2, 1, toupper(value2[i + 1]));
+ // as long as we are changing things, let's change _ followed by lowercase to capital
+ for (string::size_type i = 1; i < value2.size() - 1; ++i) {
+ if (value2[i] == '_' && islower(value2[i + 1])) {
+ value2.replace(i, 2, 1, toupper(value2[i + 1]));
+ }
}
- }
- // final length before further checks, the string may become longer
- size_t len_before = value2.length();
+ // final length before further checks, the string may become longer
+ size_t len_before = value2.length();
- // IDL identifiers may start with "New" which interferes with the CTOR pattern
- // Adding an extra underscore to all those identifiers solves this
- if ((len_before >= 3) && (value2.substr(0, 3) == "New")) {
- value2 += '_';
- }
+ // IDL identifiers may start with "New" which interferes with the CTOR pattern
+ // Adding an extra underscore to all those identifiers solves this
+ if( (len_before >= 3) && (value2.substr(0,3) == "New")) {
+ value2 += '_';
+ }
- // IDL identifiers may end with "Args"/"Result" which interferes with the implicit service
- // function structs
- // Adding another extra underscore to all those identifiers solves this
- // Suppress this check for the actual helper struct names
- if (!is_args_or_result) {
- bool ends_with_args = (len_before >= 4) && (value2.substr(len_before - 4, 4) == "Args");
- bool ends_with_rslt = (len_before >= 6) && (value2.substr(len_before - 6, 6) == "Result");
- if (ends_with_args || ends_with_rslt) {
- value2 += '_';
+ // IDL identifiers may end with "Args"/"Result" which interferes with the implicit service function structs
+ // Adding another extra underscore to all those identifiers solves this
+ // Suppress this check for the actual helper struct names
+ if(!is_args_or_result) {
+ bool ends_with_args = (len_before >= 4) && (value2.substr(len_before-4,4) == "Args");
+ bool ends_with_rslt = (len_before >= 6) && (value2.substr(len_before-6,6) == "Result");
+ if( ends_with_args || ends_with_rslt) {
+ value2 += '_';
+ }
}
- }
- return prefix + value2;
+ return prefix + value2;
}
-std::string t_go_generator::new_prefix(const std::string& value) {
- if (value.size() <= 0) {
- return value;
- }
+std::string t_go_generator::new_prefix(const std::string& value)
+{
+ if (value.size() <= 0) {
+ return value;
+ }
- string::size_type dot_pos = value.rfind('.');
- if (dot_pos != string::npos) {
- return value.substr(0, dot_pos + 1) + "New" + publicize(value.substr(dot_pos + 1));
- }
- return "New" + publicize(value);
+ string::size_type dot_pos = value.rfind('.');
+ if (dot_pos != string::npos) {
+ return value.substr(0, dot_pos + 1) + "New" + publicize(value.substr(dot_pos + 1));
+ }
+ return "New" + publicize(value);
}
-std::string t_go_generator::privatize(const std::string& value) {
- if (value.size() <= 0) {
- return value;
- }
+std::string t_go_generator::privatize(const std::string& value)
+{
+ if (value.size() <= 0) {
+ return value;
+ }
- std::string value2(value);
+ std::string value2(value);
- if (!islower(value2[0])) {
- value2[0] = tolower(value2[0]);
- }
+ if (!islower(value2[0])) {
+ value2[0] = tolower(value2[0]);
+ }
- // as long as we are changing things, let's change _ followed by lowercase to capital
- for (string::size_type i = 1; i < value2.size() - 1; ++i) {
- if (value2[i] == '_' && isalpha(value2[i + 1])) {
- value2.replace(i, 2, 1, toupper(value2[i + 1]));
+ // as long as we are changing things, let's change _ followed by lowercase to capital
+ for (string::size_type i = 1; i < value2.size() - 1; ++i) {
+ if (value2[i] == '_' && isalpha(value2[i + 1])) {
+ value2.replace(i, 2, 1, toupper(value2[i + 1]));
+ }
}
- }
- return value2;
+ return value2;
}
-std::string t_go_generator::variable_name_to_go_name(const std::string& value) {
- if (value.size() <= 0) {
- return value;
- }
+std::string t_go_generator::variable_name_to_go_name(const std::string& value)
+{
+ if (value.size() <= 0) {
+ return value;
+ }
- std::string value2(value);
- std::transform(value2.begin(), value2.end(), value2.begin(), ::tolower);
+ std::string value2(value);
+ std::transform(value2.begin(), value2.end(), value2.begin(), ::tolower);
- switch (value[0]) {
- case 'b':
- case 'B':
- if (value2 != "break") {
- return value;
- }
+ switch (value[0]) {
+ case 'b':
+ case 'B':
+ if (value2 != "break") {
+ return value;
+ }
- break;
+ break;
- case 'c':
- case 'C':
- if (value2 != "case" && value2 != "chan" && value2 != "const" && value2 != "continue") {
- return value;
- }
+ case 'c':
+ case 'C':
+ if (value2 != "case" && value2 != "chan" && value2 != "const" && value2 != "continue") {
+ return value;
+ }
- break;
+ break;
- case 'd':
- case 'D':
- if (value2 != "default" && value2 != "defer") {
- return value;
- }
+ case 'd':
+ case 'D':
+ if (value2 != "default" && value2 != "defer") {
+ return value;
+ }
- break;
+ break;
- case 'e':
- case 'E':
- if (value2 != "else" && value2 != "error") {
- return value;
- }
+ case 'e':
+ case 'E':
+ if (value2 != "else" && value2 != "error") {
+ return value;
+ }
- break;
+ break;
- case 'f':
- case 'F':
- if (value2 != "fallthrough" && value2 != "for" && value2 != "func") {
- return value;
- }
+ case 'f':
+ case 'F':
+ if (value2 != "fallthrough" && value2 != "for" && value2 != "func") {
+ return value;
+ }
- break;
+ break;
- case 'g':
- case 'G':
- if (value2 != "go" && value2 != "goto") {
- return value;
- }
+ case 'g':
+ case 'G':
+ if (value2 != "go" && value2 != "goto") {
+ return value;
+ }
- break;
+ break;
- case 'i':
- case 'I':
- if (value2 != "if" && value2 != "import" && value2 != "interface") {
- return value;
- }
+ case 'i':
+ case 'I':
+ if (value2 != "if" && value2 != "import" && value2 != "interface") {
+ return value;
+ }
- break;
+ break;
- case 'm':
- case 'M':
- if (value2 != "map") {
- return value;
- }
+ case 'm':
+ case 'M':
+ if (value2 != "map") {
+ return value;
+ }
- break;
+ break;
- case 'p':
- case 'P':
- if (value2 != "package") {
- return value;
- }
+ case 'p':
+ case 'P':
+ if (value2 != "package") {
+ return value;
+ }
- break;
+ break;
- case 'r':
- case 'R':
- if (value2 != "range" && value2 != "return") {
- return value;
- }
+ case 'r':
+ case 'R':
+ if (value2 != "range" && value2 != "return") {
+ return value;
+ }
- break;
+ break;
- case 's':
- case 'S':
- if (value2 != "select" && value2 != "struct" && value2 != "switch") {
- return value;
- }
+ case 's':
+ case 'S':
+ if (value2 != "select" && value2 != "struct" && value2 != "switch") {
+ return value;
+ }
- break;
+ break;
- case 't':
- case 'T':
- if (value2 != "type") {
- return value;
- }
+ case 't':
+ case 'T':
+ if (value2 != "type") {
+ return value;
+ }
- break;
+ break;
- case 'v':
- case 'V':
- if (value2 != "var") {
- return value;
- }
+ case 'v':
+ case 'V':
+ if (value2 != "var") {
+ return value;
+ }
- break;
+ break;
- default:
- return value;
- }
+ default:
+ return value;
+ }
- return value2 + "_a1";
+ return value2 + "_a1";
}
+
/**
* Prepares for file generation by opening up the necessary file output
* streams.
*
* @param tprogram The program to generate
*/
-void t_go_generator::init_generator() {
- // Make output directory
- string module = get_real_go_module(program_);
- string target = module;
- package_dir_ = get_out_dir();
+void t_go_generator::init_generator()
+{
+ // Make output directory
+ string module = get_real_go_module(program_);
+ string target = module;
+ package_dir_ = get_out_dir();
+
+ while (true) {
+ // TODO: Do better error checking here.
+ MKDIR(package_dir_.c_str());
+
+ if (module.empty()) {
+ break;
+ }
- while (true) {
- // TODO: Do better error checking here.
- MKDIR(package_dir_.c_str());
+ string::size_type pos = module.find('.');
- if (module.empty()) {
- break;
+ if (pos == string::npos) {
+ package_dir_ += "/";
+ package_dir_ += module;
+ package_name_ = module;
+ module.clear();
+ } else {
+ package_dir_ += "/";
+ package_dir_ += module.substr(0, pos);
+ module.erase(0, pos + 1);
+ }
}
- string::size_type pos = module.find('.');
+ string::size_type loc;
- if (pos == string::npos) {
- package_dir_ += "/";
- package_dir_ += module;
- package_name_ = module;
- module.clear();
- } else {
- package_dir_ += "/";
- package_dir_ += module.substr(0, pos);
- module.erase(0, pos + 1);
+ while ((loc = target.find(".")) != string::npos) {
+ target.replace(loc, 1, 1, '/');
}
- }
- string::size_type loc;
+ // Make output files
+ f_types_name_ = package_dir_ + "/" + "ttypes.go";
+ f_types_.open(f_types_name_.c_str());
- while ((loc = target.find(".")) != string::npos) {
- target.replace(loc, 1, 1, '/');
- }
+ f_consts_name_ = package_dir_ + "/" + "constants.go";
+ f_consts_.open(f_consts_name_.c_str());
- // Make output files
- f_types_name_ = package_dir_ + "/" + "ttypes.go";
- f_types_.open(f_types_name_.c_str());
+ vector<t_service*> services = program_->get_services();
+ vector<t_service*>::iterator sv_iter;
- f_consts_name_ = package_dir_ + "/" + "constants.go";
- f_consts_.open(f_consts_name_.c_str());
-
- vector<t_service*> services = program_->get_services();
- vector<t_service*>::iterator sv_iter;
+ for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) {
+ string service_dir = package_dir_ + "/" + underscore((*sv_iter)->get_name()) + "-remote";
+ MKDIR(service_dir.c_str());
+ }
- for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) {
- string service_dir = package_dir_ + "/" + underscore((*sv_iter)->get_name()) + "-remote";
- MKDIR(service_dir.c_str());
- }
+ // Print header
+ f_types_ <<
+ go_autogen_comment() <<
+ go_package() <<
+ render_includes() <<
+ render_import_protection();
- // Print header
- f_types_ << go_autogen_comment() << go_package() << render_includes()
- << render_import_protection();
+ f_consts_ <<
+ go_autogen_comment() <<
+ go_package() <<
+ render_includes();
- f_consts_ << go_autogen_comment() << go_package() << render_includes();
+ f_const_values_ << endl << "func init() {" << endl;
- f_const_values_ << endl << "func init() {" << endl;
}
/**
* Renders all the imports necessary for including another Thrift program
*/
-string t_go_generator::render_includes() {
- const vector<t_program*>& includes = program_->get_includes();
- string result = "";
- string unused_prot = "";
+string t_go_generator::render_includes()
+{
+ const vector<t_program*>& includes = program_->get_includes();
+ string result = "";
+ string unused_prot = "";
+
+ for (size_t i = 0; i < includes.size(); ++i) {
+ string go_module = get_real_go_module(includes[i]);
+ size_t found = 0;
+ for (size_t j = 0; j < go_module.size(); j++) {
+ // Import statement uses slashes ('/') in namespace
+ if (go_module[j] == '.') {
+ go_module[j] = '/';
+ found = j + 1;
+ }
+ }
- for (size_t i = 0; i < includes.size(); ++i) {
- string go_module = get_real_go_module(includes[i]);
- size_t found = 0;
- for (size_t j = 0; j < go_module.size(); j++) {
- // Import statement uses slashes ('/') in namespace
- if (go_module[j] == '.') {
- go_module[j] = '/';
- found = j + 1;
- }
+ result += "\t\"" + gen_package_prefix_ + go_module + "\"\n";
+ unused_prot += "var _ = " + go_module.substr(found) + ".GoUnusedProtection__\n";
}
- result += "\t\"" + gen_package_prefix_ + go_module + "\"\n";
- unused_prot += "var _ = " + go_module.substr(found) + ".GoUnusedProtection__\n";
- }
-
- if (includes.size() > 0) {
- result += "\n";
- }
+ if (includes.size() > 0) {
+ result += "\n";
+ }
- return go_imports_begin() + result + go_imports_end() + unused_prot;
+ return go_imports_begin() + result + go_imports_end() + unused_prot;
}
string t_go_generator::render_import_protection() {
@@ -702,15 +714,17 @@ string t_go_generator::render_import_protection() {
/**
* Renders all the imports necessary to use the accelerated TBinaryProtocol
*/
-string t_go_generator::render_fastbinary_includes() {
- return "";
+string t_go_generator::render_fastbinary_includes()
+{
+ return "";
}
/**
* Autogen'd comment
*/
-string t_go_generator::go_autogen_comment() {
- return
+string t_go_generator::go_autogen_comment()
+{
+ return
std::string() +
"// Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")\n"
"// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n\n";
@@ -719,19 +733,21 @@ string t_go_generator::go_autogen_comment() {
/**
* Prints standard thrift package
*/
-string t_go_generator::go_package() {
- return string("package ") + package_name_ + "\n\n";
+string t_go_generator::go_package()
+{
+ return string("package ") + package_name_ + "\n\n";
}
/**
* Render the beginning of the import statement
*/
-string t_go_generator::go_imports_begin() {
- return string(
- "import (\n"
- "\t\"bytes\"\n"
- "\t\"fmt\"\n"
- "\t\"" + gen_thrift_import_ + "\"\n");
+string t_go_generator::go_imports_begin()
+{
+ return
+ string("import (\n"
+ "\t\"bytes\"\n"
+ "\t\"fmt\"\n"
+ "\t\"" + gen_thrift_import_ + "\"\n");
}
/**
@@ -740,27 +756,30 @@ string t_go_generator::go_imports_begin() {
* These "_ =" prevent the go compiler complaining about used imports.
* This will have to do in lieu of more intelligent import statement construction
*/
-string t_go_generator::go_imports_end() {
- return string(
- ")\n\n"
- "// (needed to ensure safety because of naive import list construction.)\n"
- "var _ = thrift.ZERO\n"
- "var _ = fmt.Printf\n"
- "var _ = bytes.Equal\n\n");
+string t_go_generator::go_imports_end()
+{
+ return
+ string(
+ ")\n\n"
+ "// (needed to ensure safety because of naive import list construction.)\n"
+ "var _ = thrift.ZERO\n"
+ "var _ = fmt.Printf\n"
+ "var _ = bytes.Equal\n\n");
}
/**
* Closes the type files
*/
-void t_go_generator::close_generator() {
- f_const_values_ << "}" << endl << endl;
- f_consts_ << f_const_values_.str();
+void t_go_generator::close_generator()
+{
+ f_const_values_ << "}" << endl << endl;
+ f_consts_ << f_const_values_.str();
- // Close types and constants files
- f_consts_.close();
- f_types_.close();
- format_go_output(f_types_name_);
- format_go_output(f_consts_name_);
+ // Close types and constants files
+ f_consts_.close();
+ f_types_.close();
+ format_go_output(f_types_name_);
+ format_go_output(f_consts_name_);
}
/**
@@ -768,20 +787,23 @@ void t_go_generator::close_generator() {
*
* @param ttypedef The type definition
*/
-void t_go_generator::generate_typedef(t_typedef* ttypedef) {
- generate_go_docstring(f_types_, ttypedef);
- string new_type_name(publicize(ttypedef->get_symbolic()));
- string base_type(type_to_go_type(ttypedef->get_type()));
+void t_go_generator::generate_typedef(t_typedef* ttypedef)
+{
+ generate_go_docstring(f_types_, ttypedef);
+ string new_type_name(publicize(ttypedef->get_symbolic()));
+ string base_type(type_to_go_type(ttypedef->get_type()));
- if (base_type == new_type_name) {
- return;
- }
+ if (base_type == new_type_name) {
+ return;
+ }
- f_types_ << "type " << new_type_name << " " << base_type << endl << endl;
- // Generate a convenience function that converts an instance of a type
- // (which may be a constant) into a pointer to an instance of a type.
- f_types_ << "func " << new_type_name << "Ptr(v " << new_type_name << ") *" << new_type_name
- << " { return &v }" << endl << endl;
+ f_types_ <<
+ "type " << new_type_name << " " << base_type << endl << endl;
+ // Generate a convenience function that converts an instance of a type
+ // (which may be a constant) into a pointer to an instance of a type.
+ f_types_ <<
+ "func " << new_type_name << "Ptr(v " << new_type_name << ") *" << new_type_name <<
+ " { return &v }" << endl << endl;
}
/**
@@ -790,73 +812,87 @@ void t_go_generator::generate_typedef(t_typedef* ttypedef) {
*
* @param tenum The enumeration
*/
-void t_go_generator::generate_enum(t_enum* tenum) {
- std::ostringstream to_string_mapping, from_string_mapping;
- std::string tenum_name(publicize(tenum->get_name()));
- generate_go_docstring(f_types_, tenum);
- f_types_ << "type " << tenum_name << " int64" << endl << "const (" << endl;
- to_string_mapping << indent() << "func (p " << tenum_name << ") String() string {" << endl
- << indent() << " switch p {" << endl;
- from_string_mapping << indent() << "func " << tenum_name << "FromString(s string) (" << tenum_name
- << ", error) {" << endl << indent() << " switch s {" << endl;
- vector<t_enum_value*> constants = tenum->get_constants();
- vector<t_enum_value*>::iterator c_iter;
- int value = -1;
-
- for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
- value = (*c_iter)->get_value();
-
- string iter_std_name(escape_string((*c_iter)->get_name()));
- string iter_name((*c_iter)->get_name());
- f_types_ << indent() << " " << tenum_name << "_" << iter_name << ' ' << tenum_name << " = "
- << value << endl;
- // Dictionaries to/from string names of enums
- to_string_mapping << indent() << " case " << tenum_name << "_" << iter_name << ": return \""
- << tenum_name << "_" << iter_std_name << "\"" << endl;
-
- if (iter_std_name != escape_string(iter_name)) {
- from_string_mapping << indent() << " case \"" << tenum_name << "_" << iter_std_name
- << "\", \"" << escape_string(iter_name) << "\": return " << tenum_name
- << "_" << iter_name << ", nil " << endl;
- } else {
- from_string_mapping << indent() << " case \"" << tenum_name << "_" << iter_std_name
- << "\": return " << tenum_name << "_" << iter_name << ", nil " << endl;
+void t_go_generator::generate_enum(t_enum* tenum)
+{
+ std::ostringstream to_string_mapping, from_string_mapping;
+ std::string tenum_name(publicize(tenum->get_name()));
+ generate_go_docstring(f_types_, tenum);
+ f_types_ <<
+ "type " << tenum_name << " int64" << endl <<
+ "const (" << endl;
+ to_string_mapping <<
+ indent() << "func (p " << tenum_name << ") String() string {" << endl <<
+ indent() << " switch p {" << endl;
+ from_string_mapping <<
+ indent() << "func " << tenum_name << "FromString(s string) (" << tenum_name << ", error) {" << endl <<
+ indent() << " switch s {" << endl;
+ vector<t_enum_value*> constants = tenum->get_constants();
+ vector<t_enum_value*>::iterator c_iter;
+ int value = -1;
+
+ for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
+ value = (*c_iter)->get_value();
+
+ string iter_std_name(escape_string((*c_iter)->get_name()));
+ string iter_name((*c_iter)->get_name());
+ f_types_ <<
+ indent() << " " << tenum_name << "_" << iter_name << ' ' << tenum_name << " = " << value << endl;
+ // Dictionaries to/from string names of enums
+ to_string_mapping <<
+ indent() << " case " << tenum_name << "_" << iter_name << ": return \"" << tenum_name << "_" << iter_std_name << "\"" << endl;
+
+ if (iter_std_name != escape_string(iter_name)) {
+ from_string_mapping <<
+ indent() << " case \"" << tenum_name << "_" << iter_std_name << "\", \"" << escape_string(iter_name) << "\": return " <<
+ tenum_name << "_" << iter_name << ", nil " << endl;
+ } else {
+ from_string_mapping <<
+ indent() << " case \"" << tenum_name << "_" << iter_std_name << "\": return " <<
+ tenum_name << "_" << iter_name << ", nil " << endl;
+ }
}
- }
- to_string_mapping << indent() << " }" << endl << indent() << " return \"<UNSET>\"" << endl
- << indent() << "}" << endl;
- from_string_mapping << indent() << " }" << endl << indent() << " return " << tenum_name
- << "(0),"
- << " fmt.Errorf(\"not a valid " << tenum_name << " string\")" << endl
- << indent() << "}" << endl;
+ to_string_mapping <<
+ indent() << " }" << endl <<
+ indent() << " return \"<UNSET>\"" << endl <<
+ indent() << "}" << endl;
+ from_string_mapping <<
+ indent() << " }" << endl <<
+ indent() << " return " << tenum_name << "(0)," <<
+ " fmt.Errorf(\"not a valid " << tenum_name << " string\")" << endl <<
+ indent() << "}" << endl;
- f_types_ << ")" << endl << endl << to_string_mapping.str() << endl << from_string_mapping.str()
- << endl << endl;
+ f_types_ << ")" << endl << endl
+ << to_string_mapping.str() << endl
+ << from_string_mapping.str() << endl << endl;
- // Generate a convenience function that converts an instance of an enum
- // (which may be a constant) into a pointer to an instance of that enum
- // type.
- f_types_ << "func " << tenum_name << "Ptr(v " << tenum_name << ") *" << tenum_name
- << " { return &v }" << endl << endl;
+ // Generate a convenience function that converts an instance of an enum
+ // (which may be a constant) into a pointer to an instance of that enum
+ // type.
+ f_types_ <<
+ "func " << tenum_name << "Ptr(v " << tenum_name << ") *" << tenum_name <<
+ " { return &v }" << endl << endl;
}
+
/**
* Generate a constant value
*/
-void t_go_generator::generate_const(t_const* tconst) {
- t_type* type = tconst->get_type();
- string name = publicize(tconst->get_name());
- t_const_value* value = tconst->get_value();
-
- if (type->is_base_type() || type->is_enum()) {
- indent(f_consts_) << "const " << name << " = " << render_const_value(type, value, name) << endl;
- } else {
- f_const_values_ << indent() << name << " = " << render_const_value(type, value, name) << endl
- << endl;
+void t_go_generator::generate_const(t_const* tconst)
+{
+ t_type* type = tconst->get_type();
+ string name = publicize(tconst->get_name());
+ t_const_value* value = tconst->get_value();
+
+ if (type->is_base_type() || type->is_enum()) {
+ indent(f_consts_) << "const " << name << " = " << render_const_value(type, value, name) << endl;
+ } else {
+ f_const_values_ <<
+ indent() << name << " = " << render_const_value(type, value, name) << endl << endl;
- f_consts_ << indent() << "var " << name << " " << type_to_go_type(type) << endl;
- }
+ f_consts_ <<
+ indent() << "var " << name << " " << type_to_go_type(type) << endl;
+ }
}
/**
@@ -864,137 +900,150 @@ void t_go_generator::generate_const(t_const* tconst) {
* is NOT performed in this function as it is always run beforehand using the
* validate_types method in main.cc
*/
-string t_go_generator::render_const_value(t_type* type, t_const_value* value, const string& name) {
- 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:
- if (((t_base_type*)type)->is_binary()) {
- out << "[]byte(\"" << get_escaped_string(value) << "\")";
- } else {
- 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;
+string t_go_generator::render_const_value(t_type* type, t_const_value* value, const string& name)
+{
+ type = get_true_type(type);
+ std::ostringstream out;
- 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 << "&" << publicize(type_name(type)) << "{";
- indent_up();
- 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;
+ if (type->is_base_type()) {
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- t_type* field_type = NULL;
+ switch (tbase) {
+ case t_base_type::TYPE_STRING:
+ if (((t_base_type*)type)->is_binary()) {
+ out << "[]byte(\"" << get_escaped_string(value) << "\")";
+ } else {
+ out << '"' << get_escaped_string(value) << '"';
+ }
- 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();
- }
- }
+ break;
- if (field_type == NULL) {
- throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
- }
+ case t_base_type::TYPE_BOOL:
+ out << (value->get_integer() > 0 ? "true" : "false");
+ break;
- if (field_type->is_base_type() || field_type->is_enum()) {
- out << endl << indent() << publicize(v_iter->first->get_string()) << ": "
- << render_const_value(field_type, v_iter->second, name) << ",";
- } else {
- string k(tmp("k"));
- string v(tmp("v"));
- out << endl << indent() << v << " := " << render_const_value(field_type, v_iter->second, v)
- << endl << indent() << name << "." << publicize(v_iter->first->get_string()) << " = "
- << v;
- }
- }
+ 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;
- out << "}";
+ case t_base_type::TYPE_DOUBLE:
+ if (value->get_type() == t_const_value::CV_INTEGER) {
+ out << value->get_integer();
+ } else {
+ out << value->get_double();
+ }
- indent_down();
- } else if (type->is_map()) {
- t_type* ktype = ((t_map*)type)->get_key_type();
- t_type* vtype = ((t_map*)type)->get_val_type();
- const map<t_const_value*, t_const_value*>& val = value->get_map();
- out << "map[" << type_to_go_type(ktype) << "]" << type_to_go_type(vtype, true) << "{" << endl;
- indent_up();
- map<t_const_value*, t_const_value*>::const_iterator v_iter;
+ break;
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- out << indent() << render_const_value(ktype, v_iter->first, name) << ": "
- << render_const_value(vtype, v_iter->second, name) << "," << endl;
- }
+ 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 <<
+ "&" << publicize(type_name(type)) << "{";
+ indent_up();
+ 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;
+
+ 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 (field_type->is_base_type() || field_type->is_enum()) {
+ out << endl <<
+ indent() << publicize(v_iter->first->get_string()) << ": " << render_const_value(field_type, v_iter->second, name) << ",";
+ } else {
+ string k(tmp("k"));
+ string v(tmp("v"));
+ out << endl <<
+ indent() << v << " := " << render_const_value(field_type, v_iter->second, v) << endl <<
+ indent() << name << "." << publicize(v_iter->first->get_string()) << " = " << v;
+ }
+ }
- indent_down();
- out << indent() << "}";
- } else if (type->is_list()) {
- t_type* etype = ((t_list*)type)->get_elem_type();
- const vector<t_const_value*>& val = value->get_list();
- out << "[]" << type_to_go_type(etype) << "{" << endl;
- indent_up();
- vector<t_const_value*>::const_iterator v_iter;
+ out << "}";
+
+ indent_down();
+ } else if (type->is_map()) {
+ t_type* ktype = ((t_map*)type)->get_key_type();
+ t_type* vtype = ((t_map*)type)->get_val_type();
+ const map<t_const_value*, t_const_value*>& val = value->get_map();
+ out <<
+ "map[" << type_to_go_type(ktype) << "]" << type_to_go_type(vtype, true) << "{" << endl;
+ indent_up();
+ map<t_const_value*, t_const_value*>::const_iterator v_iter;
+
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
+ out <<
+ indent() << render_const_value(ktype, v_iter->first, name) << ": " <<
+ render_const_value(vtype, v_iter->second, name) << "," << endl;
+ }
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- out << indent() << render_const_value(etype, *v_iter, name) << ", ";
- }
+ indent_down();
+ out <<
+ indent() << "}";
+ } else if (type->is_list()) {
+ t_type* etype = ((t_list*)type)->get_elem_type();
+ const vector<t_const_value*>& val = value->get_list();
+ out <<
+ "[]" << type_to_go_type(etype) << "{" << endl;
+ indent_up();
+ vector<t_const_value*>::const_iterator v_iter;
+
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
+ out <<
+ indent() << render_const_value(etype, *v_iter, name) << ", ";
+ }
- indent_down();
- out << indent() << "}";
- } else if (type->is_set()) {
- t_type* etype = ((t_set*)type)->get_elem_type();
- const vector<t_const_value*>& val = value->get_list();
- out << "map[" << type_to_go_key_type(etype) << "]bool{" << endl;
- indent_up();
- vector<t_const_value*>::const_iterator v_iter;
+ indent_down();
+ out <<
+ indent() << "}";
+ } else if (type->is_set()) {
+ t_type* etype = ((t_set*)type)->get_elem_type();
+ const vector<t_const_value*>& val = value->get_list();
+ out <<
+ "map[" << type_to_go_key_type(etype) << "]bool{" << endl;
+ indent_up();
+ vector<t_const_value*>::const_iterator v_iter;
+
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
+ out <<
+ indent() << render_const_value(etype, *v_iter, name) << ": true," << endl;
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- out << indent() << render_const_value(etype, *v_iter, name) << ": true," << endl;
- }
+ }
- indent_down();
- out << indent() << "}";
- } else {
- throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
- }
+ indent_down();
+ out <<
+ indent() << "}";
+ } else {
+ throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
+ }
- return out.str();
+ return out.str();
}
/**
* Generates a go struct
*/
-void t_go_generator::generate_struct(t_struct* tstruct) {
- generate_go_struct(tstruct, false);
+void t_go_generator::generate_struct(t_struct* tstruct)
+{
+ generate_go_struct(tstruct, false);
}
/**
@@ -1003,46 +1052,47 @@ void t_go_generator::generate_struct(t_struct* tstruct) {
*
* @param txception The struct definition
*/
-void t_go_generator::generate_xception(t_struct* txception) {
- generate_go_struct(txception, true);
+void t_go_generator::generate_xception(t_struct* txception)
+{
+ generate_go_struct(txception, true);
}
/**
* Generates a go struct
*/
-void t_go_generator::generate_go_struct(t_struct* tstruct, bool is_exception) {
- generate_go_struct_definition(f_types_, tstruct, is_exception);
+void t_go_generator::generate_go_struct(t_struct* tstruct,
+ bool is_exception)
+{
+ generate_go_struct_definition(f_types_, tstruct, is_exception);
}
void t_go_generator::get_publicized_name_and_def_value(t_field* tfield,
string* OUT_pub_name,
t_const_value** OUT_def_value) const {
- const string base_field_name = tfield->get_name();
- const string escaped_field_name = escape_string(base_field_name);
- const string go_safe_name = variable_name_to_go_name(escaped_field_name);
- *OUT_pub_name = publicize(go_safe_name);
- *OUT_def_value = tfield->get_value();
+ const string base_field_name = tfield->get_name();
+ const string escaped_field_name = escape_string(base_field_name);
+ const string go_safe_name = variable_name_to_go_name(escaped_field_name);
+ *OUT_pub_name = publicize(go_safe_name);
+ *OUT_def_value = tfield->get_value();
}
void t_go_generator::generate_go_struct_initializer(ofstream& out,
- t_struct* tstruct,
- bool is_args_or_result) {
- out << publicize(type_name(tstruct), is_args_or_result) << "{";
- const vector<t_field*>& members = tstruct->get_members();
- for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end();
- ++m_iter) {
- bool pointer_field = is_pointer_field(*m_iter);
- string publicized_name;
- t_const_value* def_value;
- get_publicized_name_and_def_value(*m_iter, &publicized_name, &def_value);
- if (!pointer_field && def_value != NULL && !omit_initialization(*m_iter)) {
- out << endl << indent() << publicized_name << ": "
- << render_field_initial_value(*m_iter, (*m_iter)->get_name(), pointer_field) << ","
- << endl;
- }
- }
-
- out << "}" << endl;
+ t_struct* tstruct,
+ bool is_args_or_result)
+{
+ out << publicize(type_name(tstruct), is_args_or_result) << "{";
+ const vector<t_field*>& members = tstruct->get_members();
+ for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+ bool pointer_field = is_pointer_field(*m_iter);
+ string publicized_name;
+ t_const_value* def_value;
+ get_publicized_name_and_def_value(*m_iter, &publicized_name, &def_value);
+ if (!pointer_field && def_value != NULL && !omit_initialization(*m_iter)) {
+ out << endl << indent() << publicized_name << ": " << render_field_initial_value(*m_iter, (*m_iter)->get_name(), pointer_field) << "," << endl;
+ }
+ }
+
+ out << "}" << endl;
}
/**
@@ -1051,369 +1101,419 @@ void t_go_generator::generate_go_struct_initializer(ofstream& out,
* @param tstruct The struct definition
*/
void t_go_generator::generate_go_struct_definition(ofstream& out,
- t_struct* tstruct,
- bool is_exception,
- bool is_result,
- bool is_args) {
- const vector<t_field*>& members = tstruct->get_members();
- const vector<t_field*>& sorted_members = tstruct->get_sorted_members();
- vector<t_field*>::const_iterator m_iter;
-
- std::string tstruct_name(publicize(tstruct->get_name(), is_args || is_result));
- out << indent() << "type " << tstruct_name << " struct {" << endl;
- /*
- Here we generate the structure specification for the fastbinary codec.
- These specifications have the following structure:
- thrift_spec -> tuple of item_spec
- item_spec -> nil | (tag, type_enum, name, spec_args, default)
- tag -> integer
- type_enum -> TType.I32 | TType.STRING | TType.STRUCT | ...
- name -> string_literal
- default -> nil # Handled by __init__
- spec_args -> nil # For simple types
- | (type_enum, spec_args) # Value type for list/set
- | (type_enum, spec_args, type_enum, spec_args)
- # Key and value for map
- | (class_name, spec_args_ptr) # For struct/exception
- class_name -> identifier # Basically a pointer to the class
- spec_args_ptr -> expression # just class_name.spec_args
-
- TODO(dreiss): Consider making this work for structs with negative tags.
- */
- // TODO(dreiss): Look into generating an empty tuple instead of nil
- // for structures with no members.
- // TODO(dreiss): Test encoding of structs where some inner structs
- // don't have thrift_spec.
- indent_up();
-
- if (sorted_members.empty() || (sorted_members[0]->get_key() >= 0)) {
- int sorted_keys_pos = 0;
-
- for (m_iter = sorted_members.begin(); m_iter != sorted_members.end(); ++m_iter) {
- if (sorted_keys_pos != (*m_iter)->get_key()) {
- int first_unused = std::max(1, sorted_keys_pos++);
- while (sorted_keys_pos != (*m_iter)->get_key()) {
- ++sorted_keys_pos;
- }
- int last_unused = sorted_keys_pos - 1;
- if (first_unused < last_unused) {
- indent(out) << "// unused fields # " << first_unused << " to " << last_unused << endl;
- } else if (first_unused == last_unused) {
- indent(out) << "// unused field # " << first_unused << endl;
- }
- }
-
- t_type* fieldType = (*m_iter)->get_type();
- string goType = type_to_go_type_with_opt(fieldType, is_pointer_field(*m_iter));
- string gotag("json:\"" + escape_string((*m_iter)->get_name()) + "\"");
- std::map<string, string>::iterator it = (*m_iter)->annotations_.find("go.tag");
- if (it != (*m_iter)->annotations_.end()) {
- gotag = it->second;
- }
- indent(out) << publicize(variable_name_to_go_name((*m_iter)->get_name())) << " " << goType
- << " `thrift:\"" << escape_string((*m_iter)->get_name()) << ","
- << sorted_keys_pos;
-
- if ((*m_iter)->get_req() == t_field::T_REQUIRED) {
- out << ",required";
- }
-
- out << "\" " << gotag << "`" << endl;
- sorted_keys_pos++;
- }
- } else {
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- // This fills in default values, as opposed to nulls
- out << indent() << publicize((*m_iter)->get_name()) << " "
- << type_to_go_type((*m_iter)->get_type()) << endl;
- }
- }
-
- indent_down();
- out << indent() << "}" << endl << endl << indent() << "func New" << tstruct_name << "() *"
- << tstruct_name << " {" << endl << indent() << " return &";
- generate_go_struct_initializer(out, tstruct, is_result || is_args);
- out << indent() << "}" << endl << endl;
- // Default values for optional fields
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- string publicized_name;
- t_const_value* def_value;
- get_publicized_name_and_def_value(*m_iter, &publicized_name, &def_value);
- t_type* fieldType = (*m_iter)->get_type();
- string goType = type_to_go_type_with_opt(fieldType, false);
- string def_var_name = tstruct_name + "_" + publicized_name + "_DEFAULT";
- if ((*m_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*m_iter)) {
- out << indent() << "var " << def_var_name << " " << goType;
- if (def_value != NULL) {
- out << " = " << render_const_value(fieldType, def_value, (*m_iter)->get_name());
- }
- out << endl;
- }
- if (is_pointer_field(*m_iter)) {
- string goOptType = type_to_go_type_with_opt(fieldType, true);
- string maybepointer = goOptType != goType ? "*" : "";
- out << indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() "
- << goType << " {" << endl << indent() << " if !p.IsSet" << publicized_name << "() {"
- << endl << indent() << " return " << def_var_name << endl << indent() << " }" << endl
- << indent() << "return " << maybepointer << "p." << publicized_name << endl << indent()
- << "}" << endl;
+ t_struct* tstruct,
+ bool is_exception,
+ bool is_result,
+ bool is_args)
+{
+ const vector<t_field*>& members = tstruct->get_members();
+ const vector<t_field*>& sorted_members = tstruct->get_sorted_members();
+ vector<t_field*>::const_iterator m_iter;
+
+ std::string tstruct_name(publicize(tstruct->get_name(), is_args||is_result));
+ out <<
+ indent() << "type " << tstruct_name << " struct {" << endl;
+ /*
+ Here we generate the structure specification for the fastbinary codec.
+ These specifications have the following structure:
+ thrift_spec -> tuple of item_spec
+ item_spec -> nil | (tag, type_enum, name, spec_args, default)
+ tag -> integer
+ type_enum -> TType.I32 | TType.STRING | TType.STRUCT | ...
+ name -> string_literal
+ default -> nil # Handled by __init__
+ spec_args -> nil # For simple types
+ | (type_enum, spec_args) # Value type for list/set
+ | (type_enum, spec_args, type_enum, spec_args)
+ # Key and value for map
+ | (class_name, spec_args_ptr) # For struct/exception
+ class_name -> identifier # Basically a pointer to the class
+ spec_args_ptr -> expression # just class_name.spec_args
+
+ TODO(dreiss): Consider making this work for structs with negative tags.
+ */
+ // TODO(dreiss): Look into generating an empty tuple instead of nil
+ // for structures with no members.
+ // TODO(dreiss): Test encoding of structs where some inner structs
+ // don't have thrift_spec.
+ indent_up();
+
+ if (sorted_members.empty() || (sorted_members[0]->get_key() >= 0)) {
+ int sorted_keys_pos = 0;
+
+ for (m_iter = sorted_members.begin(); m_iter != sorted_members.end(); ++m_iter) {
+ if( sorted_keys_pos != (*m_iter)->get_key()) {
+ int first_unused = std::max(1,sorted_keys_pos++);
+ while( sorted_keys_pos != (*m_iter)->get_key()) {
+ ++sorted_keys_pos;
+ }
+ int last_unused = sorted_keys_pos - 1;
+ if (first_unused < last_unused) {
+ indent(out) << "// unused fields # " << first_unused << " to "<< last_unused << endl;
+ } else if (first_unused == last_unused) {
+ indent(out) << "// unused field # " << first_unused << endl;
+ }
+ }
+
+ t_type* fieldType = (*m_iter)->get_type();
+ string goType = type_to_go_type_with_opt(fieldType, is_pointer_field(*m_iter));
+ string gotag("json:\"" + escape_string((*m_iter)->get_name()) + "\"");
+ std::map<string, string>::iterator it = (*m_iter)->annotations_.find("go.tag");
+ if (it != (*m_iter)->annotations_.end()) {
+ gotag = it->second;
+ }
+ indent(out) << publicize(variable_name_to_go_name((*m_iter)->get_name())) << " "
+ << goType << " `thrift:\""
+ << escape_string((*m_iter)->get_name())
+ << "," << sorted_keys_pos;
+
+ if ((*m_iter)->get_req() == t_field::T_REQUIRED) {
+ out << ",required";
+ }
+
+ out << "\" " <<gotag <<"`" << endl;
+ sorted_keys_pos ++;
+ }
} else {
- out << endl << indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() "
- << goType << " {" << endl << indent() << "return p." << publicized_name << endl
- << indent() << "}" << endl;
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+ // This fills in default values, as opposed to nulls
+ out <<
+ indent() << publicize((*m_iter)->get_name()) << " " <<
+ type_to_go_type((*m_iter)->get_type()) << endl;
+ }
+ }
+
+ indent_down();
+ out <<
+ indent() << "}" << endl << endl <<
+ indent() << "func New" << tstruct_name << "() *" << tstruct_name << " {" << endl <<
+ indent() << " return &";
+ generate_go_struct_initializer(out, tstruct, is_result || is_args);
+ out <<
+ indent() << "}" << endl << endl;
+ // Default values for optional fields
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+ string publicized_name;
+ t_const_value* def_value;
+ get_publicized_name_and_def_value(*m_iter, &publicized_name, &def_value);
+ t_type* fieldType = (*m_iter)->get_type();
+ string goType = type_to_go_type_with_opt(fieldType, false);
+ string def_var_name = tstruct_name + "_" + publicized_name + "_DEFAULT";
+ if ((*m_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*m_iter)) {
+ out << indent() << "var " << def_var_name <<" "<<goType ;
+ if (def_value != NULL) {
+ out << " = " << render_const_value(fieldType, def_value, (*m_iter)->get_name()) ;
+ }
+ out <<endl;
+ }
+ if (is_pointer_field(*m_iter)) {
+ string goOptType = type_to_go_type_with_opt(fieldType, true);
+ string maybepointer = goOptType!=goType?"*":"";
+ out <<indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() "<< goType<<" {" << endl
+ <<indent() << " if !p.IsSet" <<publicized_name <<"() {" <<endl
+ <<indent() << " return " <<def_var_name <<endl
+ <<indent() << " }" <<endl
+ <<indent() << "return "<<maybepointer <<"p." <<publicized_name <<endl
+ <<indent() << "}" <<endl;
+ } else {
+ out <<endl
+ <<indent() << "func (p *" << tstruct_name << ") Get" << publicized_name << "() "<< goType<<" {" << endl
+ <<indent() << "return p." <<publicized_name <<endl
+ <<indent() << "}" <<endl;
+
+ }
}
- }
- generate_isset_helpers(out, tstruct, tstruct_name, is_result);
- generate_go_struct_reader(out, tstruct, tstruct_name, is_result);
- generate_go_struct_writer(out, tstruct, tstruct_name, is_result);
+ generate_isset_helpers(out, tstruct, tstruct_name, is_result);
+ generate_go_struct_reader(out, tstruct, tstruct_name, is_result);
+ generate_go_struct_writer(out, tstruct, tstruct_name, is_result);
- out << indent() << "func (p *" << tstruct_name << ") String() string {" << endl << indent()
- << " if p == nil {" << endl << indent() << " return \"<nil>\"" << endl << indent()
- << " }" << endl << indent() << " return fmt.Sprintf(\"" << escape_string(tstruct_name)
- << "(%+v)\", *p)" << endl << indent() << "}" << endl << endl;
+ out <<
+ indent() << "func (p *" << tstruct_name << ") String() string {" << endl <<
+ indent() << " if p == nil {" << endl <<
+ indent() << " return \"<nil>\"" << endl <<
+ indent() << " }" << endl <<
+ indent() << " return fmt.Sprintf(\"" << escape_string(tstruct_name) << "(%+v)\", *p)" << endl <<
+ indent() << "}" << endl << endl;
- if (is_exception) {
- out << indent() << "func (p *" << tstruct_name << ") Error() string {" << endl << indent()
- << " return p.String()" << endl << indent() << "}" << endl << endl;
- }
+ if(is_exception) {
+ out <<
+ indent() << "func (p *" << tstruct_name << ") Error() string {" << endl <<
+ indent() << " return p.String()" << endl <<
+ indent() << "}" << endl << endl;
+ }
}
/**
* Generates the IsSet helper methods for a struct
*/
void t_go_generator::generate_isset_helpers(ofstream& out,
- t_struct* tstruct,
- const string& tstruct_name,
- bool is_result) {
- (void)is_result;
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
- const string escaped_tstruct_name(escape_string(tstruct->get_name()));
-
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- const string field_name(
- publicize(variable_name_to_go_name(escape_string((*f_iter)->get_name()))));
- if ((*f_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*f_iter)) {
- out << indent() << "func (p *" << tstruct_name << ") IsSet" << field_name << "() bool {"
- << endl;
- indent_up();
- t_type* ttype = (*f_iter)->get_type()->get_true_type();
- bool is_byteslice = ttype->is_base_type() && ((t_base_type*)ttype)->is_binary();
- bool compare_to_nil_only = ttype->is_set() || ttype->is_list() || ttype->is_map()
- || (is_byteslice && !(*f_iter)->get_value());
- if (is_pointer_field(*f_iter) || compare_to_nil_only) {
- out << indent() << "return p." << field_name << " != nil" << endl;
- } else {
- string def_var_name = tstruct_name + "_" + field_name + "_DEFAULT";
- if (is_byteslice) {
- out << indent() << "return !bytes.Equal(p." << field_name << ", " << def_var_name << ")"
- << endl;
- } else {
- out << indent() << "return p." << field_name << " != " << def_var_name << endl;
+ t_struct* tstruct,
+ const string& tstruct_name,
+ bool is_result)
+{
+ (void) is_result;
+ const vector<t_field*>& fields = tstruct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+ const string escaped_tstruct_name(escape_string(tstruct->get_name()));
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ const string field_name(publicize(variable_name_to_go_name(escape_string((*f_iter)->get_name()))));
+ if ((*f_iter)->get_req() == t_field::T_OPTIONAL || is_pointer_field(*f_iter)) {
+ out <<
+ indent() << "func (p *" << tstruct_name << ") IsSet" << field_name << "() bool {" << endl;
+ indent_up();
+ t_type* ttype = (*f_iter)->get_type()->get_true_type();
+ bool is_byteslice = ttype->is_base_type() && ((t_base_type*)ttype)->is_binary() ;
+ bool compare_to_nil_only = ttype->is_set()
+ || ttype->is_list()
+ || ttype->is_map()
+ || (is_byteslice && !(*f_iter)->get_value());
+ if (is_pointer_field(*f_iter) || compare_to_nil_only) {
+ out <<
+ indent() << "return p." << field_name << " != nil" << endl;
+ } else {
+ string def_var_name = tstruct_name + "_" + field_name + "_DEFAULT";
+ if (is_byteslice) {
+ out << indent() << "return !bytes.Equal(p." << field_name << ", "<<def_var_name << ")" << endl;
+ } else {
+ out << indent() << "return p." << field_name << " != "<<def_var_name << endl;
+ }
+ }
+ indent_down();
+ out <<
+ indent() << "}" << endl << endl;
}
- }
- indent_down();
- out << indent() << "}" << endl << endl;
}
- }
}
/**
* Generates the read method for a struct
*/
void t_go_generator::generate_go_struct_reader(ofstream& out,
- t_struct* tstruct,
- const string& tstruct_name,
- bool is_result) {
- (void)is_result;
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
- string escaped_tstruct_name(escape_string(tstruct->get_name()));
- out << indent() << "func (p *" << tstruct_name << ") Read(iprot thrift.TProtocol) error {"
- << endl;
- indent_up();
- out << indent() << "if _, err := iprot.ReadStructBegin(); err != nil {" << endl << indent()
- << " return fmt.Errorf(\"%T read error: %s\", p, err)" << endl << indent() << "}" << endl;
- // Loop over reading in fields
- indent(out) << "for {" << endl;
- indent_up();
- // Read beginning field marker
- out << indent() << "_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()" << endl << indent()
- << "if err != nil {" << endl << indent()
- << " return fmt.Errorf(\"%T field %d read error: %s\", p, fieldId, err)" << endl << indent()
- << "}" << endl;
- // Check for field STOP marker and break
- out << indent() << "if fieldTypeId == thrift.STOP { break; }" << endl;
-
- string thriftFieldTypeId;
- // Generate deserialization code for known cases
- int32_t field_id = -1;
-
- // Switch statement on the field we are reading, false if no fields present
- bool have_switch = !fields.empty();
- if (have_switch) {
- indent(out) << "switch fieldId {" << endl;
- }
-
- // All the fields we know
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- field_id = (*f_iter)->get_key();
-
- // if negative id, ensure we generate a valid method name
- string field_method_prefix("ReadField");
-
- if (field_id < 0) {
- field_method_prefix += "_";
- field_id *= -1;
- }
-
- out << indent() << "case " << field_id << ":" << endl;
+ t_struct* tstruct,
+ const string& tstruct_name,
+ bool is_result)
+{
+ (void) is_result;
+ const vector<t_field*>& fields = tstruct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+ string escaped_tstruct_name(escape_string(tstruct->get_name()));
+ out <<
+ indent() << "func (p *" << tstruct_name << ") Read(iprot thrift.TProtocol) error {" << endl;
indent_up();
- thriftFieldTypeId = type_to_enum((*f_iter)->get_type());
+ out <<
+ indent() << "if _, err := iprot.ReadStructBegin(); err != nil {" << endl <<
+ indent() << " return fmt.Errorf(\"%T read error: %s\", p, err)" << endl <<
+ indent() << "}" << endl;
+ // Loop over reading in fields
+ indent(out) << "for {" << endl;
+ indent_up();
+ // Read beginning field marker
+ out <<
+ indent() << "_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()" << endl <<
+ indent() << "if err != nil {" << endl <<
+ indent() << " return fmt.Errorf(\"%T field %d read error: %s\", p, fieldId, err)" << endl <<
+ indent() << "}" << endl;
+ // Check for field STOP marker and break
+ out <<
+ indent() << "if fieldTypeId == thrift.STOP { break; }" << endl;
+
+ string thriftFieldTypeId;
+ // Generate deserialization code for known cases
+ int32_t field_id = -1;
+
+ // Switch statement on the field we are reading, false if no fields present
+ bool have_switch = !fields.empty();
+ if( have_switch) {
+ indent(out) << "switch fieldId {" << endl;
+ }
+
+ // All the fields we know
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ field_id = (*f_iter)->get_key();
- if (thriftFieldTypeId == "thrift.BINARY") {
- thriftFieldTypeId = "thrift.STRING";
+ // if negative id, ensure we generate a valid method name
+ string field_method_prefix("ReadField");
+
+ if (field_id < 0) {
+ field_method_prefix += "_";
+ field_id *= -1;
+ }
+
+ out <<
+ indent() <<"case " << field_id << ":" << endl;
+ indent_up();
+ thriftFieldTypeId = type_to_enum((*f_iter)->get_type());
+
+ if (thriftFieldTypeId == "thrift.BINARY") {
+ thriftFieldTypeId = "thrift.STRING";
+ }
+
+ out <<
+ indent() << "if err := p." << field_method_prefix << field_id << "(iprot); err != nil {" << endl <<
+ indent() << " return err" << endl <<
+ indent() << "}" << endl;
+ indent_down();
}
- out << indent() << "if err := p." << field_method_prefix << field_id << "(iprot); err != nil {"
- << endl << indent() << " return err" << endl << indent() << "}" << endl;
- indent_down();
- }
+ // Begin switch default case
+ if( have_switch) {
+ out <<
+ indent() << "default:" << endl;
+ indent_up();
+ }
- // Begin switch default case
- if (have_switch) {
- out << indent() << "default:" << endl;
- indent_up();
- }
+ // Skip unknown fields in either case
+ out <<
+ indent() << "if err := iprot.Skip(fieldTypeId); err != nil {" << endl <<
+ indent() << " return err" << endl <<
+ indent() << "}" << endl;
- // Skip unknown fields in either case
- out << indent() << "if err := iprot.Skip(fieldTypeId); err != nil {" << endl << indent()
- << " return err" << endl << indent() << "}" << endl;
+ // End switch default case
+ if( have_switch) {
+ indent_down();
+ out <<
+ indent() << "}" << endl;
+ }
- // End switch default case
- if (have_switch) {
+ // Read field end marker
+ out <<
+ indent() << "if err := iprot.ReadFieldEnd(); err != nil {" << endl <<
+ indent() << " return err" << endl <<
+ indent() << "}" << endl;
indent_down();
- out << indent() << "}" << endl;
- }
-
- // Read field end marker
- out << indent() << "if err := iprot.ReadFieldEnd(); err != nil {" << endl << indent()
- << " return err" << endl << indent() << "}" << endl;
- indent_down();
- out << indent() << "}" << endl << indent() << "if err := iprot.ReadStructEnd(); err != nil {"
- << endl << indent() << " return fmt.Errorf(\"%T read struct end error: %s\", p, err)" << endl
- << indent() << "}" << endl << indent() << "return nil" << endl;
- indent_down();
- out << indent() << "}" << endl << endl;
-
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- string field_type_name(publicize((*f_iter)->get_type()->get_name()));
- string field_name(publicize((*f_iter)->get_name()));
- string field_method_prefix("ReadField");
- int32_t field_id = (*f_iter)->get_key();
-
- if (field_id < 0) {
- field_method_prefix += "_";
- field_id *= -1;
- }
-
- out << indent() << "func (p *" << tstruct_name << ") " << field_method_prefix << field_id
- << "(iprot thrift.TProtocol) error {" << endl;
- indent_up();
- generate_deserialize_field(out, *f_iter, false, "p.");
+ out <<
+ indent() << "}" << endl <<
+ indent() << "if err := iprot.ReadStructEnd(); err != nil {" << endl <<
+ indent() << " return fmt.Errorf(\"%T read struct end error: %s\", p, err)" << endl <<
+ indent() << "}" << endl <<
+ indent() << "return nil" << endl;
indent_down();
- out << indent() << " return nil" << endl << indent() << "}" << endl << endl;
- }
+ out <<
+ indent() << "}" << endl << endl;
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ string field_type_name(publicize((*f_iter)->get_type()->get_name()));
+ string field_name(publicize((*f_iter)->get_name()));
+ string field_method_prefix("ReadField");
+ int32_t field_id = (*f_iter)->get_key();
+
+ if (field_id < 0) {
+ field_method_prefix += "_";
+ field_id *= -1;
+ }
+
+ out <<
+ indent() << "func (p *" << tstruct_name << ") " << field
<TRUNCATED>