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
This commit is contained in:
Bryan Duxbury 2010-11-24 00:25:57 +00:00
parent 5f9614cf9a
commit 1606f25616
3 changed files with 82 additions and 20 deletions

View File

@ -624,7 +624,7 @@ string t_java_generator::render_const_value(ofstream& out, string name, t_type*
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 @@ void t_java_generator::generate_union_constructor(ofstream& out, t_struct* tstru
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 @@ void t_java_generator::generate_union_getters_and_setters(ofstream& out, t_struc
}
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 @@ void t_java_generator::generate_java_bean_boilerplate(ofstream& out,
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 {

View File

@ -715,16 +715,14 @@ void validate_const_rec(std::string name, t_type* type, t_const_value* value) {
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;

View File

@ -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 @@ class t_const_value {
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;
}