Skip to content

Commit 4c7799b

Browse files
committed
THRIFT-3037: Support Struct Typedefs in Go Codegen
Client: Go
1 parent 8a6bcc7 commit 4c7799b

File tree

5 files changed

+118
-18
lines changed

5 files changed

+118
-18
lines changed

compiler/cpp/src/thrift/generate/t_go_generator.cc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,8 @@ void t_go_generator::generate_typedef(t_typedef* ttypedef) {
766766
return;
767767
}
768768

769-
f_types_ << "type " << new_type_name << " " << base_type << endl << endl;
769+
f_types_ << "type " << new_type_name << " = " << base_type << endl << endl;
770+
770771
// Generate a convenience function that converts an instance of a type
771772
// (which may be a constant) into a pointer to an instance of a type.
772773
f_types_ << "func " << new_type_name << "Ptr(v " << new_type_name << ") *" << new_type_name
@@ -1175,8 +1176,9 @@ void t_go_generator::get_publicized_name_and_def_value(t_field* tfield,
11751176

11761177
void t_go_generator::generate_go_struct_initializer(ostream& out,
11771178
t_struct* tstruct,
1178-
bool is_args_or_result) {
1179-
out << publicize(type_name(tstruct), is_args_or_result) << "{";
1179+
bool is_args_or_result,
1180+
string alias_name) {
1181+
out << publicize((alias_name != "") ? alias_name : type_name(tstruct), is_args_or_result) << "{";
11801182
const vector<t_field*>& members = tstruct->get_members();
11811183
for (auto member : members) {
11821184
bool pointer_field = is_pointer_field(member);
@@ -3049,7 +3051,8 @@ void t_go_generator::generate_deserialize_field(ostream& out,
30493051
(t_struct*)type,
30503052
is_pointer_field(tfield, in_container_value),
30513053
declare,
3052-
name);
3054+
name,
3055+
(orig_type->is_typedef()) ? orig_type->get_name() : "");
30533056
} else if (type->is_container()) {
30543057
generate_deserialize_container(out, orig_type, is_pointer_field(tfield), declare, name);
30553058
} else if (type->is_base_type() || type->is_enum()) {
@@ -3150,11 +3153,12 @@ void t_go_generator::generate_deserialize_struct(ostream& out,
31503153
t_struct* tstruct,
31513154
bool pointer_field,
31523155
bool declare,
3153-
string prefix) {
3156+
string prefix,
3157+
string alias_name) {
31543158
string eq(declare ? " := " : " = ");
31553159

31563160
out << indent() << prefix << eq << (pointer_field ? "&" : "");
3157-
generate_go_struct_initializer(out, tstruct);
3161+
generate_go_struct_initializer(out, tstruct, false, alias_name);
31583162
out << indent() << "if err := " << prefix << "." << read_method_name_ << "(ctx, iprot); err != nil {" << endl;
31593163
out << indent() << " return thrift.PrependError(fmt.Sprintf(\"%T error reading struct: \", "
31603164
<< prefix << "), err)" << endl;
@@ -3921,13 +3925,11 @@ string t_go_generator::type_to_go_type(t_type* type) {
39213925
* Converts the parse type to a go type, taking into account whether the field
39223926
* associated with the type is T_OPTIONAL.
39233927
*/
3924-
string t_go_generator::type_to_go_type_with_opt(t_type* type,
3928+
string t_go_generator::type_to_go_type_with_opt(t_type* ttype,
39253929
bool optional_field) {
39263930
string maybe_pointer(optional_field ? "*" : "");
39273931

3928-
if (type->is_typedef() && ((t_typedef*)type)->is_forward_typedef()) {
3929-
type = ((t_typedef*)type)->get_true_type();
3930-
}
3932+
t_type* type = get_true_type(ttype);
39313933

39323934
if (type->is_base_type()) {
39333935
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
@@ -3970,7 +3972,7 @@ string t_go_generator::type_to_go_type_with_opt(t_type* type,
39703972
} else if (type->is_enum()) {
39713973
return maybe_pointer + publicize(type_name(type));
39723974
} else if (type->is_struct() || type->is_xception()) {
3973-
return "*" + publicize(type_name(type));
3975+
return "*" + publicize(type_name(ttype));
39743976
} else if (type->is_map()) {
39753977
t_map* t = (t_map*)type;
39763978
string keyType = type_to_go_key_type(t->get_key_type());
@@ -3984,8 +3986,6 @@ string t_go_generator::type_to_go_type_with_opt(t_type* type,
39843986
t_list* t = (t_list*)type;
39853987
string elemType = type_to_go_type(t->get_elem_type());
39863988
return maybe_pointer + string("[]") + elemType;
3987-
} else if (type->is_typedef()) {
3988-
return maybe_pointer + publicize(type_name(type));
39893989
}
39903990

39913991
throw "INVALID TYPE IN type_to_go_type: " + type->get_name();

compiler/cpp/src/thrift/generate/t_go_generator.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ class t_go_generator : public t_generator {
124124
bool is_args = false);
125125
void generate_go_struct_initializer(std::ostream& out,
126126
t_struct* tstruct,
127-
bool is_args_or_result = false);
127+
bool is_args_or_result = false,
128+
string alias_name = "");
128129
void generate_isset_helpers(std::ostream& out,
129130
t_struct* tstruct,
130131
const string& tstruct_name,
@@ -176,7 +177,8 @@ class t_go_generator : public t_generator {
176177
t_struct* tstruct,
177178
bool is_pointer_field,
178179
bool declare,
179-
std::string prefix = "");
180+
std::string prefix = "",
181+
string alias_name = "");
180182

181183
void generate_deserialize_container(std::ostream& out,
182184
t_type* ttype,

lib/go/test/Makefile.am

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ gopath: $(THRIFT) $(THRIFTTEST) \
6262
ProcessorMiddlewareTest.thrift \
6363
ClientMiddlewareExceptionTest.thrift \
6464
ValidateTest.thrift \
65-
ForwardType.thrift
65+
ForwardType.thrift \
66+
TypedefServiceTest.thrift
6667
mkdir -p gopath/src
6768
grep -v list.*map.*list.*map $(THRIFTTEST) | grep -v 'set<Insanity>' > ThriftTest.thrift
6869
$(THRIFT) $(THRIFTARGS) -r IncludesTest.thrift
@@ -98,6 +99,7 @@ gopath: $(THRIFT) $(THRIFTTEST) \
9899
$(THRIFT) $(THRIFTARGS) ClientMiddlewareExceptionTest.thrift
99100
$(THRIFT) $(THRIFTARGS) ValidateTest.thrift
100101
$(THRIFT) $(THRIFTARGS) ForwardType.thrift
102+
$(THRIFT) $(THRIFTARGS) TypedefServiceTest.thrift
101103
ln -nfs ../../tests gopath/src/tests
102104
cp -r ./dontexportrwtest gopath/src
103105
touch gopath
@@ -124,7 +126,8 @@ check: gopath
124126
./gopath/src/processormiddlewaretest \
125127
./gopath/src/clientmiddlewareexceptiontest \
126128
./gopath/src/validatetest \
127-
./gopath/src/forwardtypetest
129+
./gopath/src/forwardtypetest \
130+
./gopath/src/typedefservicetest
128131
$(GO) test github.com/apache/thrift/lib/go/thrift
129132
$(GO) test ./gopath/src/tests ./gopath/src/dontexportrwtest
130133

@@ -172,4 +175,5 @@ EXTRA_DIST = \
172175
TypedefFieldTest.thrift \
173176
UnionBinaryTest.thrift \
174177
UnionDefaultValueTest.thrift \
175-
ValidateTest.thrift
178+
ValidateTest.thrift \
179+
TypedefServiceTest.thrift
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
#
19+
20+
# We are only testing that generated code compiles, no correctness checking is done
21+
22+
struct ExampleRequest {
23+
1: required string example_field
24+
}
25+
26+
struct ExampleResponse {
27+
1: required string example_field
28+
}
29+
30+
struct ExampleOptionalRequest {
31+
1: optional string example_field
32+
}
33+
34+
struct ExampleOptionalResponse {
35+
1: optional string example_field
36+
}
37+
38+
struct ExampleNested {
39+
1: required string example_field
40+
}
41+
42+
struct ExampleOptionalNestedRequest {
43+
1: optional ExampleNested example_field
44+
}
45+
46+
struct ExampleOptionalNestedResponse {
47+
1: optional ExampleNested example_field
48+
}
49+
50+
typedef ExampleRequest TypedefExampleRequest
51+
typedef ExampleResponse TypedefExampleResponse
52+
53+
typedef string PrimativeTypedefExampleRequest
54+
typedef string PrimativeTypedefExampleResponse
55+
56+
service TypeDefService {
57+
ExampleResponse exampleMethod(1: ExampleRequest request)
58+
TypedefExampleResponse typedefExampleMethod(1: TypedefExampleRequest request)
59+
string primativeExampleMethod(1: string request)
60+
PrimativeTypedefExampleResponse primativeTypedefExampleMethod(1: PrimativeTypedefExampleRequest request)
61+
ExampleOptionalResponse exampleOptionalMethod(1: ExampleOptionalRequest request)
62+
ExampleOptionalNestedResponse exampleOptionalNestedMethod(1: ExampleOptionalNestedRequest request)
63+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package tests
21+
22+
import (
23+
"testing"
24+
25+
"github.com/apache/thrift/lib/go/test/gopath/src/typedefservicetest"
26+
)
27+
28+
func TestTypedefService(t *testing.T) {
29+
// We need to import the generated code to ensure it compiles
30+
_ = &typedefservicetest.TypedefExampleRequest{}
31+
}

0 commit comments

Comments
 (0)