THRIFT-2505 go struct should always be a pointer to avoid copying of potentially size-unbounded structs
Client: Go
Patch: Aleksey Pesternikov
This closes #116
commit 69bbf0e2b148cb1f48e24f46d181cc4d5dc35786
Author: Aleksey Pesternikov <ap@alekseys-mbp.att.net>
Date: 2014-05-02T15:45:15Z
struct should always be a pointer to avoid copying of potentially size-unbounded structs
diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc
index 6e887a7..c581ffa 100644
--- a/compiler/cpp/src/generate/t_go_generator.cc
+++ b/compiler/cpp/src/generate/t_go_generator.cc
@@ -334,6 +334,8 @@
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;
}
@@ -347,7 +349,7 @@
}
t_type* type = tfield->get_type()->get_true_type();
//Structs in containers are pointers
- if (in_container_value && type->is_struct()) {
+ if (type->is_struct() || type->is_xception()) {
return true;
}
if (!(tfield->get_req() == t_field::T_OPTIONAL)) {
@@ -2532,7 +2534,7 @@
for (xf_iter = x_fields.begin(); xf_iter != x_fields.end(); ++xf_iter) {
f_service_ <<
- indent() << " case *" << type_to_go_type(((*xf_iter)->get_type())) << ":" << endl <<
+ indent() << " case " << type_to_go_type(((*xf_iter)->get_type())) << ":" << endl <<
indent() << "result." << publicize(variable_name_to_go_name((*xf_iter)->get_name())) << " = v" << endl;
}
@@ -3441,10 +3443,7 @@
} else if (type->is_enum()) {
return maybe_pointer + publicize(type_name(type));
} else if (type->is_struct() || type->is_xception()) {
- if (is_container_value) {
- maybe_pointer = "*";
- }
- return maybe_pointer + publicize(type_name(type));
+ return "*" + publicize(type_name(type));
} else if (type->is_map()) {
t_map* t = (t_map*)type;
string keyType = type_to_go_key_type(t->get_key_type());
diff --git a/lib/go/test/ServicesTest.thrift b/lib/go/test/ServicesTest.thrift
index 1b8be36..c79f472 100644
--- a/lib/go/test/ServicesTest.thrift
+++ b/lib/go/test/ServicesTest.thrift
@@ -106,4 +106,6 @@
struct_a struct_a_func_1ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1)
struct_a struct_a_func_2ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1, 2:total_disaster err2)
+ struct_a struct_a_func_1struct_a(1: struct_a st)
+
}
diff --git a/lib/go/test/tests/struct_args_rets_test.go b/lib/go/test/tests/struct_args_rets_test.go
new file mode 100644
index 0000000..c965865
--- /dev/null
+++ b/lib/go/test/tests/struct_args_rets_test.go
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+package tests
+
+import (
+ st "ServicesTest"
+)
+
+//this function is never called, it will fail to compile if check is failed
+func staticCheckStructArgsResults() {
+ //Check that struct args and results are passed by reference
+ var sa *st.StructA = &st.StructA{}
+ var iface st.AServ
+ var err error
+
+ sa, err = iface.StructAFunc_1structA(sa)
+ _ = err
+ _ = sa
+}