THRIFT-2247 Go generator doesn't deal well with map keys of type binary
Patch: Tonnerre Lombard & Aleksey Pesternikov
diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc
index b962378..559a20e 100644
--- a/compiler/cpp/src/generate/t_go_generator.cc
+++ b/compiler/cpp/src/generate/t_go_generator.cc
@@ -140,7 +140,8 @@
bool declare,
std::string prefix = "",
bool inclass = false,
- bool coerceData = false);
+ bool coerceData = false,
+ bool inkey = false);
void generate_deserialize_struct(std::ofstream &out,
t_struct* tstruct,
@@ -169,7 +170,8 @@
void generate_serialize_field(std::ofstream &out,
t_field* tfield,
- std::string prefix = "");
+ std::string prefix = "",
+ bool inkey = false);
void generate_serialize_struct(std::ofstream &out,
t_struct* tstruct,
@@ -2442,7 +2444,8 @@
bool declare,
string prefix,
bool inclass,
- bool coerceData)
+ bool coerceData,
+ bool inkey)
{
t_type* orig_type = tfield->get_type();
t_type* type = get_true_type(orig_type);
@@ -2462,7 +2465,9 @@
} else if (type->is_base_type() || type->is_enum()) {
if (declare) {
- out << "var " << tfield->get_name() << " " << type_to_go_type(tfield->get_type()) << endl;
+ string type_name = inkey ? type_to_go_key_type(tfield->get_type()) :
+ type_to_go_type(tfield->get_type());
+ out << "var " << tfield->get_name() << " " << type_name << endl;
}
indent(out) <<
@@ -2478,7 +2483,7 @@
break;
case t_base_type::TYPE_STRING:
- if (((t_base_type*)type)->is_binary()) {
+ if (((t_base_type*)type)->is_binary() && !inkey) {
out << "ReadBinary()";
} else {
out << "ReadString()";
@@ -2586,7 +2591,7 @@
indent() << "if err != nil {" << endl <<
indent() << " return fmt.Errorf(\"error reading map begin: %s\")" << endl <<
indent() << "}" << endl <<
- indent() << prefix << eq << "make(map[" << type_to_go_type(t->get_key_type()) << "]" << type_to_go_type(t->get_val_type()) << ", size)" << endl;
+ indent() << prefix << eq << "make(map[" << type_to_go_key_type(t->get_key_type()) << "]" << type_to_go_type(t->get_val_type()) << ", size)" << endl;
} else if (ttype->is_set()) {
t_set* t = (t_set*)ttype;
out <<
@@ -2594,7 +2599,7 @@
indent() << "if err != nil {" << endl <<
indent() << " return fmt.Errorf(\"error reading set being: %s\")" << endl <<
indent() << "}" << endl <<
- indent() << prefix << eq << "make(map[" << type_to_go_type(t->get_elem_type()) << "]bool, size)" << endl;
+ indent() << prefix << eq << "make(map[" << type_to_go_key_type(t->get_elem_type()) << "]bool, size)" << endl;
} else if (ttype->is_list()) {
t_list* t = (t_list*)ttype;
out <<
@@ -2656,7 +2661,7 @@
string val = tmp("_val");
t_field fkey(tmap->get_key_type(), key);
t_field fval(tmap->get_val_type(), val);
- generate_deserialize_field(out, &fkey, true);
+ generate_deserialize_field(out, &fkey, true, "", false, false, true);
generate_deserialize_field(out, &fval, true);
indent(out) <<
prefix << "[" << key << "] = " << val << endl;
@@ -2702,7 +2707,8 @@
*/
void t_go_generator::generate_serialize_field(ofstream &out,
t_field* tfield,
- string prefix)
+ string prefix,
+ bool inkey)
{
t_type* type = get_true_type(tfield->get_type());
string name(prefix + publicize(variable_name_to_go_name(tfield->get_name())));
@@ -2734,7 +2740,7 @@
break;
case t_base_type::TYPE_STRING:
- if (((t_base_type*)type)->is_binary()) {
+ if (((t_base_type*)type)->is_binary() && !inkey) {
out << "WriteBinary(" << name << ")";
} else {
out << "WriteString(string(" << name << "))";
@@ -2882,7 +2888,7 @@
string viter)
{
t_field kfield(tmap->get_key_type(), "");
- generate_serialize_field(out, &kfield, kiter);
+ generate_serialize_field(out, &kfield, kiter, true);
t_field vfield(tmap->get_val_type(), "");
generate_serialize_field(out, &vfield, viter);
}
@@ -3193,6 +3199,10 @@
throw "Cannot produce a valid type for a Go map key: " + type_to_go_type(type) + " - aborting.";
}
+ if (resolved_type->is_string() &&
+ ((t_base_type*) resolved_type)->is_binary())
+ return "string";
+
return type_to_go_type(type);
}