Skip to content

Commit

Permalink
THRIFT-5650: Implement UUID in Go compiler
Browse files Browse the repository at this point in the history
Client: go
  • Loading branch information
fishy committed Oct 26, 2022
1 parent cea5559 commit 2acfe0f
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 55 deletions.
62 changes: 60 additions & 2 deletions compiler/cpp/src/thrift/generate/t_go_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ bool t_go_generator::omit_initialization(t_field* tfield) {
} else {
return value->get_double() == 0.;
}

case t_base_type::TYPE_UUID:
// it's hard to detect all zero uuid here, so just always inline it.
return false;

default:
throw "compiler error: unhandled type";
}
Expand Down Expand Up @@ -150,7 +155,9 @@ bool t_go_generator::is_pointer_field(t_field* tfield, bool in_container_value)
case t_base_type::TYPE_I32:
case t_base_type::TYPE_I64:
case t_base_type::TYPE_DOUBLE:
case t_base_type::TYPE_UUID:
return !has_default;

default:
break;
}
Expand Down Expand Up @@ -867,7 +874,7 @@ 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()) {
if (type->is_enum() || (type->is_base_type() && ((t_base_type*)type)->get_base() != t_base_type::TYPE_UUID)) {
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
Expand All @@ -884,8 +891,10 @@ void t_go_generator::generate_const(t_const* tconst) {
*/
string t_go_generator::render_const_value(t_type* type, t_const_value* value, const string& name, bool opt) {
string typedef_opt_ptr;
string typedef_opt;
if (type->is_typedef()) {
typedef_opt_ptr = type_name(type) + "Ptr";
typedef_opt = publicize(type_name(type));
typedef_opt_ptr = typedef_opt + "Ptr";
}
type = get_true_type(type);
std::ostringstream out;
Expand Down Expand Up @@ -966,6 +975,19 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co
out << '"' + get_escaped_string(value) + '"';
break;

case t_base_type::TYPE_UUID:
if (typedef_opt_ptr != "") {
out << typedef_opt_ptr << "(" << typedef_opt;
} else {
out << "thrift.TuuidPtr";
}
out << "(";
out << "thrift.Must(thrift.ParseTuuid(\"" + get_escaped_string(value) + "\"))";
if (typedef_opt_ptr != "") {
out << ")";
}
break;

default:
throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
}
Expand Down Expand Up @@ -1007,6 +1029,17 @@ string t_go_generator::render_const_value(t_type* type, t_const_value* value, co

break;

case t_base_type::TYPE_UUID:
if (typedef_opt != "") {
out << typedef_opt << "(";
}
out << "thrift.Must(thrift.ParseTuuid(\"" + get_escaped_string(value) + "\"))";
if (typedef_opt != "") {
out << ")";
}

break;

default:
throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
}
Expand Down Expand Up @@ -2425,6 +2458,15 @@ void t_go_generator::generate_service_remote(t_service* tservice) {
f_remote << indent() << "}" << endl;
break;

case t_base_type::TYPE_UUID:
f_remote << indent() << "argvalue" << i << ", " << err
<< " := (thrift.ParseTuuid(flag.Arg(" << flagArg << ")))" << endl;
f_remote << indent() << "if " << err << " != nil {" << endl;
f_remote << indent() << " Usage()" << endl;
f_remote << indent() << " return" << endl;
f_remote << indent() << "}" << endl;
break;

default:
throw("Invalid base type in generate_service_remote");
}
Expand Down Expand Up @@ -2539,6 +2581,7 @@ void t_go_generator::generate_service_remote(t_service* tservice) {
case t_base_type::TYPE_I32:
case t_base_type::TYPE_I64:
case t_base_type::TYPE_DOUBLE:
case t_base_type::TYPE_UUID:
f_remote << "value" << i;
break;

Expand Down Expand Up @@ -3052,6 +3095,10 @@ void t_go_generator::generate_deserialize_field(ostream& out,
out << "ReadDouble(ctx)";
break;

case t_base_type::TYPE_UUID:
out << "ReadUUID(ctx)";
break;

default:
throw "compiler error: no Go name for base type " + t_base_type::t_base_name(tbase);
}
Expand Down Expand Up @@ -3301,6 +3348,10 @@ void t_go_generator::generate_serialize_field(ostream& out,
out << "WriteDouble(ctx, float64(" << name << "))";
break;

case t_base_type::TYPE_UUID:
out << "WriteUUID(ctx, thrift.Tuuid(" << name << "))";
break;

default:
throw "compiler error: no Go name for base type " + t_base_type::t_base_name(tbase);
}
Expand Down Expand Up @@ -3500,6 +3551,7 @@ void t_go_generator::generate_go_equals(ostream& out, t_type* ori_type, string t
case t_base_type::TYPE_I32:
case t_base_type::TYPE_I64:
case t_base_type::TYPE_DOUBLE:
case t_base_type::TYPE_UUID:
out << tgt << " != " << src;
break;

Expand Down Expand Up @@ -3807,6 +3859,9 @@ string t_go_generator::type_to_enum(t_type* type) {
case t_base_type::TYPE_DOUBLE:
return "thrift.DOUBLE";

case t_base_type::TYPE_UUID:
return "thrift.UUID";

default:
break;
}
Expand Down Expand Up @@ -3897,6 +3952,9 @@ string t_go_generator::type_to_go_type_with_opt(t_type* type,
case t_base_type::TYPE_DOUBLE:
return maybe_pointer + "float64";

case t_base_type::TYPE_UUID:
return maybe_pointer + "thrift.Tuuid";

default:
break;
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/cpp/src/thrift/generate/validator_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const char* list_delimiter = "[], ";
std::vector<validation_rule*> validation_parser::parse_field(
t_type* type,
std::map<std::string, std::vector<std::string>>& annotations) {
std::vector<validation_rule*> empty_rules;
if (type->is_typedef()) {
type = type->get_true_type();
}
Expand All @@ -58,7 +59,7 @@ std::vector<validation_rule*> validation_parser::parse_field(
switch (tbase) {
case t_base_type::TYPE_UUID:
case t_base_type::TYPE_VOID:
break;
return empty_rules;
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
Expand Down Expand Up @@ -547,4 +548,4 @@ validation_value::validation_function* validation_parser::get_validation_functio
+ annotation_value;
}
return function;
}
}
17 changes: 17 additions & 0 deletions lib/go/test/EqualsTest.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
typedef i8 mybyte
typedef string mystr
typedef binary mybin
typedef uuid myuuid

enum EnumFoo {
e1
Expand Down Expand Up @@ -51,6 +52,10 @@ struct BasicEqualsFoo {
22: optional mystr OptMyStrFoo,
23: mybin MyBinFoo,
24: optional mybin OptMyBinFoo,
25: uuid UUIDFoo,
26: optional uuid OptUUIDFoo,
27: myuuid MyUUIDFoo,
28: optional myuuid OptMyUUIDFoo,
}

struct StructEqualsFoo {
Expand Down Expand Up @@ -79,6 +84,10 @@ struct ListEqualsFoo {
18: optional list<mystr> OptMyStrListFoo,
19: list<mybin> MyBinListFoo,
20: optional list<mybin> OptMyBinListFoo,
21: list<uuid> UUIDListFoo,
22: optional list<uuid> OptUUIDListFoo,
23: list<myuuid> MyUUIDListFoo,
24: optional list<myuuid> OptMyUUIDListFoo,
}

struct SetEqualsFoo {
Expand All @@ -102,6 +111,10 @@ struct SetEqualsFoo {
18: optional set<mystr> OptMyStrSetFoo,
19: set<mybin> MyBinSetFoo,
20: optional set<mybin> OptMyBinSetFoo,
21: set<uuid> UUIDSetFoo,
22: optional set<uuid> OptUUIDSetFoo,
23: set<myuuid> MyUUIDSetFoo,
24: optional set<myuuid> OptMyUUIDSetFoo,
}

struct MapEqualsFoo {
Expand All @@ -125,4 +138,8 @@ struct MapEqualsFoo {
18: optional map<i64, mybyte> OptInt64MyByteMapFoo,
19: map<mybyte, i64> MyByteInt64MapFoo,
20: optional map<mybyte, i64> OptMyByteInt64MapFoo,
21: map<i64, uuid> UUIDMapFoo,
22: optional map<i64, uuid> OptUUIDMapFoo,
23: map<i64, myuuid> MyUUIDMapFoo,
24: optional map<i64, myuuid> OptMyUUIDMapFoo,
}
37 changes: 30 additions & 7 deletions lib/go/test/tests/equals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ import (
"strconv"
"testing"

"github.com/apache/thrift/lib/go/thrift"

"github.com/apache/thrift/lib/go/test/gopath/src/equalstest"
)

var (
equalstestUUID1 = thrift.Must(thrift.ParseTuuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
equalstestUUID2 = thrift.Must(thrift.ParseTuuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
)

func TestEquals(t *testing.T) {
// test basic field
basicTgt, basicSrc := genBasicFoo(), genBasicFoo()
Expand Down Expand Up @@ -117,19 +124,19 @@ func TestEquals(t *testing.T) {
func genBasicFoo() *equalstest.BasicEqualsFoo {
return &equalstest.BasicEqualsFoo{
BoolFoo: true,
OptBoolFoo: &(&struct{ x bool }{true}).x,
OptBoolFoo: thrift.BoolPtr(true),
I8Foo: 1,
OptI8Foo: &(&struct{ x int8 }{1}).x,
OptI8Foo: thrift.Int8Ptr(1),
I16Foo: 2,
OptI16Foo: &(&struct{ x int16 }{2}).x,
OptI16Foo: thrift.Int16Ptr(2),
I32Foo: 3,
OptI32Foo: &(&struct{ x int32 }{3}).x,
OptI32Foo: thrift.Int32Ptr(3),
I64Foo: 4,
OptI64Foo: &(&struct{ x int64 }{4}).x,
OptI64Foo: thrift.Int64Ptr(4),
DoubleFoo: 5,
OptDoubleFoo: &(&struct{ x float64 }{5}).x,
OptDoubleFoo: thrift.Float64Ptr(6),
StrFoo: "6",
OptStrFoo: &(&struct{ x string }{"6"}).x,
OptStrFoo: thrift.StringPtr("6"),
BinFoo: []byte("7"),
OptBinFoo: []byte("7"),
EnumFoo: equalstest.EnumFoo_e1,
Expand All @@ -140,6 +147,10 @@ func genBasicFoo() *equalstest.BasicEqualsFoo {
OptMyStrFoo: equalstest.MystrPtr(equalstest.Mystr("9")),
MyBinFoo: equalstest.Mybin("10"),
OptMyBinFoo: equalstest.Mybin("10"),
UUIDFoo: equalstestUUID1,
OptUUIDFoo: thrift.TuuidPtr(equalstestUUID1),
MyUUIDFoo: equalstest.Myuuid(equalstestUUID1),
OptMyUUIDFoo: equalstest.MyuuidPtr(equalstest.Myuuid(equalstestUUID1)),
}
}

Expand Down Expand Up @@ -172,6 +183,10 @@ func genListFoo() *equalstest.ListEqualsFoo {
OptMyStrListFoo: []equalstest.Mystr{equalstest.Mystr("6"), equalstest.Mystr("5"), equalstest.Mystr("4"), equalstest.Mystr("3"), equalstest.Mystr("2"), equalstest.Mystr("1")},
MyBinListFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")},
OptMyBinListFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")},
UUIDListFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2},
OptUUIDListFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2},
MyUUIDListFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)},
OptMyUUIDListFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)},
}
}

Expand All @@ -197,6 +212,10 @@ func genSetFoo() *equalstest.SetEqualsFoo {
OptMyStrSetFoo: []equalstest.Mystr{equalstest.Mystr("6"), equalstest.Mystr("5"), equalstest.Mystr("4"), equalstest.Mystr("3"), equalstest.Mystr("2"), equalstest.Mystr("1")},
MyBinSetFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")},
OptMyBinSetFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")},
UUIDSetFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2},
OptUUIDSetFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2},
MyUUIDSetFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)},
OptMyUUIDSetFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)},
}
}

Expand Down Expand Up @@ -227,6 +246,10 @@ func genMapFoo() *equalstest.MapEqualsFoo {
OptInt64MyByteMapFoo: map[int64]equalstest.Mybyte{6: equalstest.Mybyte(6), 5: equalstest.Mybyte(5), 4: equalstest.Mybyte(4), 3: equalstest.Mybyte(3), 2: equalstest.Mybyte(2), 1: equalstest.Mybyte(1)},
MyByteInt64MapFoo: map[equalstest.Mybyte]int64{equalstest.Mybyte(6): 6, equalstest.Mybyte(5): 5, equalstest.Mybyte(4): 4, equalstest.Mybyte(3): 3, equalstest.Mybyte(2): 2, equalstest.Mybyte(1): 1},
OptMyByteInt64MapFoo: map[equalstest.Mybyte]int64{equalstest.Mybyte(6): 6, equalstest.Mybyte(5): 5, equalstest.Mybyte(4): 4, equalstest.Mybyte(3): 3, equalstest.Mybyte(2): 2, equalstest.Mybyte(1): 1},
UUIDMapFoo: map[int64]thrift.Tuuid{1: equalstestUUID1, 2: equalstestUUID2},
OptUUIDMapFoo: map[int64]thrift.Tuuid{1: equalstestUUID1, 2: equalstestUUID2},
MyUUIDMapFoo: map[int64]equalstest.Myuuid{1: equalstest.Myuuid(equalstestUUID1), 2: equalstest.Myuuid(equalstestUUID2)},
OptMyUUIDMapFoo: map[int64]equalstest.Myuuid{1: equalstest.Myuuid(equalstestUUID1), 2: equalstest.Myuuid(equalstestUUID2)},
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/go/thrift/json_protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,8 @@ func (p *TJSONProtocol) TypeIdToString(fieldType TType) (string, error) {
return "set", nil
case LIST:
return "lst", nil
case UUID:
return "uid", nil
}

e := fmt.Errorf("Unknown fieldType: %d", int(fieldType))
Expand Down Expand Up @@ -554,6 +556,8 @@ func (p *TJSONProtocol) StringToTypeId(fieldType string) (TType, error) {
return TType(SET), nil
case "lst":
return TType(LIST), nil
case "uid":
return TType(UUID), nil
}

e := fmt.Errorf("Unknown type identifier: %s", fieldType)
Expand Down
14 changes: 11 additions & 3 deletions test/ConstantsDemo.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@
namespace cpp yozone
namespace erl consts_
namespace haxe constantsDemo
namespace go constantsdemo

typedef uuid myUUID

struct thing {
1: i32 hello,
2: i32 goodbye
3: uuid id
4: myUUID my_id
5: optional myUUID my_optional_id
}

enum enumconstants {
Expand All @@ -51,22 +56,25 @@ const double GEn_DU = 085.2355
const string GEN_STRING = "asldkjasfd"

const double e10 = 1e10 // fails with 0.9.3 and earlier
const double e11 = -1e10
const double e11 = -1e10

// uuids are accepted with or without curly braces
const uuid GEN_UUID = '00000000-4444-CCCC-ffff-0123456789ab'
const uuid GEN_GUID = '{00112233-4455-6677-8899-aaBBccDDeeFF}'

const myUUID MY_UUID = '00000000-4444-CCCC-ffff-0123456789ab'
const myUUID MY_GUID = '{00112233-4455-6677-8899-aaBBccDDeeFF}'

const map<i32,i32> GEN_MAP = { 35532 : 233, 43523 : 853 }
const list<i32> GEN_LIST = [ 235235, 23598352, 3253523 ]

const map<i32, map<i32, i32>> GEN_MAPMAP = { 235 : { 532 : 53255, 235:235}}

const map<string,i32> GEN_MAP2 = { "hello" : 233, "lkj98d" : 853, 'lkjsdf' : 098325 }

const thing GEN_THING = { 'hello' : 325, 'goodbye' : 325352, 'id' : '{00112233-4455-6677-8899-aaBBccDDeeFF}' }
const thing GEN_THING = { 'hello' : 325, 'goodbye' : 325352, 'id' : '{00112233-4455-6677-8899-aaBBccDDeeFF}', 'my_id': '00000000-4444-CCCC-ffff-0123456789ab', 'my_optional_id': '00000000-4444-CCCC-ffff-0123456789ab' }

const map<i32,thing> GEN_WHAT = { 35 : { 'hello' : 325, 'goodbye' : 325352, 'id' : '00000000-4444-CCCC-ffff-0123456789ab' } }
const map<i32,thing> GEN_WHAT = { 35 : { 'hello' : 325, 'goodbye' : 325352, 'id' : '00000000-4444-CCCC-ffff-0123456789ab', 'my_id': '00000000-4444-CCCC-ffff-0123456789ab', 'my_optional_id': '00000000-4444-CCCC-ffff-0123456789ab' } }

const set<i32> GEN_SET = [ 235, 235, 53235 ]

Expand Down
Loading

0 comments on commit 2acfe0f

Please sign in to comment.