THRIFT-1006. java: Impossible to correctly qualify an enum constant in an external thrift file
Be a little more sensitive to how we parse out dots; some java generator changes to make sure things stay consistent.
THRIFT-1005. java: Give unions byte[] signature methods to go along with their ByteBuffer counterparts
Some new constructors, getters, and setters to ease migration of unions to ByteBuffer style.
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1038399 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc
index 7acd9ac..b622322 100644
--- a/compiler/cpp/src/generate/t_java_generator.cc
+++ b/compiler/cpp/src/generate/t_java_generator.cc
@@ -624,7 +624,7 @@
throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
}
} else if (type->is_enum()) {
- render << value->get_identifier();
+ render << type->get_program()->get_namespace("java") << "." << value->get_identifier_with_parent();
} else {
string t = tmp("tmp");
print_const_value(out, t, type, value, true);
@@ -770,11 +770,20 @@
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type()) << " value) {" << endl;
+ t_type* type = (*m_iter)->get_type();
+ indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() << "(" << type_name(type) << " value) {" << endl;
indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << endl;
indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(value);" << endl;
indent(out) << " return x;" << endl;
- indent(out) << "}" << endl << endl;
+ indent(out) << "}" << endl << endl;
+
+ if (type->is_base_type() && ((t_base_type*)type)->is_binary()) {
+ indent(out) << "public static " << type_name(tstruct) << " " << (*m_iter)->get_name() << "(byte[] value) {" << endl;
+ indent(out) << " " << type_name(tstruct) << " x = new " << type_name(tstruct) << "();" << endl;
+ indent(out) << " x.set" << get_cap_name((*m_iter)->get_name()) << "(ByteBuffer.wrap(value));" << endl;
+ indent(out) << " return x;" << endl;
+ indent(out) << "}" << endl << endl;
+ }
}
}
@@ -791,20 +800,47 @@
}
t_field* field = (*m_iter);
+ t_type* type = field->get_type();
+ std::string cap_name = get_cap_name(field->get_name());
generate_java_doc(out, field);
- indent(out) << "public " << type_name(field->get_type()) << " get" << get_cap_name(field->get_name()) << "() {" << endl;
- indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" << endl;
- indent(out) << " return (" << type_name(field->get_type(), true) << ")getFieldValue();" << endl;
- indent(out) << " } else {" << endl;
- indent(out) << " throw new RuntimeException(\"Cannot get field '" << field->get_name()
- << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" << endl;
- indent(out) << " }" << endl;
- indent(out) << "}" << endl;
-
+ if (type->is_base_type() && ((t_base_type*)type)->is_binary()) {
+ indent(out) << "public byte[] get" << cap_name << "() {" << endl;
+ indent(out) << " set" << cap_name << "(TBaseHelper.rightSize(buffer" << get_cap_name("for") << cap_name << "()));" << endl;
+ indent(out) << " return buffer" << get_cap_name("for") << cap_name << "().array();" << endl;
+ indent(out) << "}" << endl;
+
+ out << endl;
+
+ indent(out) << "public ByteBuffer buffer" << get_cap_name("for") << get_cap_name(field->get_name()) << "() {" << endl;
+ indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" << endl;
+ indent(out) << " return (ByteBuffer)getFieldValue();" << endl;
+ indent(out) << " } else {" << endl;
+ indent(out) << " throw new RuntimeException(\"Cannot get field '" << field->get_name()
+ << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" << endl;
+ indent(out) << " }" << endl;
+ indent(out) << "}" << endl;
+ } else {
+ indent(out) << "public " << type_name(field->get_type()) << " get" << get_cap_name(field->get_name()) << "() {" << endl;
+ indent(out) << " if (getSetField() == _Fields." << constant_name(field->get_name()) << ") {" << endl;
+ indent(out) << " return (" << type_name(field->get_type(), true) << ")getFieldValue();" << endl;
+ indent(out) << " } else {" << endl;
+ indent(out) << " throw new RuntimeException(\"Cannot get field '" << field->get_name()
+ << "' because union is currently set to \" + getFieldDesc(getSetField()).name);" << endl;
+ indent(out) << " }" << endl;
+ indent(out) << "}" << endl;
+ }
+
out << endl;
generate_java_doc(out, field);
+ if (type->is_base_type() && ((t_base_type*)type)->is_binary()) {
+ indent(out) << "public void set" << get_cap_name(field->get_name()) << "(byte[] value) {" << endl;
+ indent(out) << " set" << get_cap_name(field->get_name()) << "(ByteBuffer.wrap(value));" << endl;
+ indent(out) << "}" << endl;
+
+ out << endl;
+ }
indent(out) << "public void set" << get_cap_name(field->get_name()) << "(" << type_name(field->get_type()) << " value) {" << endl;
if (type_can_be_null(field->get_type())) {
indent(out) << " if (value == null) throw new NullPointerException();" << endl;
@@ -1856,7 +1892,7 @@
indent(out) << " return " << field_name << ".array();" << endl;
indent(out) << "}" << endl << endl;
- indent(out) << "public ByteBuffer " << get_cap_name("bufferFor") << cap_name << "() {" << endl;
+ indent(out) << "public ByteBuffer buffer" << get_cap_name("for") << cap_name << "() {" << endl;
indent(out) << " return " << field_name << ";" << endl;
indent(out) << "}" << endl << endl;
} else {
diff --git a/compiler/cpp/src/main.cc b/compiler/cpp/src/main.cc
index fa6d3ae..0c561b9 100644
--- a/compiler/cpp/src/main.cc
+++ b/compiler/cpp/src/main.cc
@@ -715,16 +715,14 @@
throw "type error: const \"" + name + "\" was declared as enum";
}
+ // see if there's a dot in the identifier
+ std::string name_portion = value->get_identifier_name();
+
const vector<t_enum_value*>& enum_values = ((t_enum*)type)->get_constants();
vector<t_enum_value*>::const_iterator c_iter;
bool found = false;
- for (c_iter = enum_values.begin(); c_iter != enum_values.end(); ++c_iter) {
- size_t sub_index = value->get_identifier().find('.');
- if (sub_index == string::npos) {
- throw "error: identifier " + value->get_identifier() + " is unqualified!";
- }
- std::string name_portion = value->get_identifier().substr(sub_index+1);
+ for (c_iter = enum_values.begin(); c_iter != enum_values.end(); ++c_iter) {
if ((*c_iter)->get_name() == name_portion) {
found = true;
break;
diff --git a/compiler/cpp/src/parse/t_const_value.h b/compiler/cpp/src/parse/t_const_value.h
index 43c28b1..ff422ae 100644
--- a/compiler/cpp/src/parse/t_const_value.h
+++ b/compiler/cpp/src/parse/t_const_value.h
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <map>
#include <vector>
+#include <string>
/**
* A const value is something parsed that could be a map, set, list, struct
@@ -129,7 +130,34 @@
std::string get_identifier() const {
return identifierVal_;
}
-
+
+ std::string get_identifier_name() const {
+ std::string ret = get_identifier();
+ size_t s = ret.find('.');
+ if (s == std::string::npos) {
+ throw "error: identifier " + ret + " is unqualified!";
+ }
+ ret = ret.substr(s+1);
+ s = ret.find('.');
+ if (s != std::string::npos) {
+ ret = ret.substr(s+1);
+ }
+ return ret;
+ }
+
+ std::string get_identifier_with_parent() const {
+ std::string ret = get_identifier();
+ size_t s = ret.find('.');
+ if (s == std::string::npos) {
+ throw "error: identifier " + ret + " is unqualified!";
+ }
+ size_t s2 = ret.find('.', s+1);
+ if (s2 != std::string::npos) {
+ ret = ret.substr(s+1);
+ }
+ return ret;
+ }
+
void set_enum(t_enum* tenum) {
enum_ = tenum;
}