From 1606f25616bbf0dc862ab6d0b9aef620027d1fcb Mon Sep 17 00:00:00 2001 From: Bryan Duxbury Date: Wed, 24 Nov 2010 00:25:57 +0000 Subject: [PATCH] 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 --- compiler/cpp/src/generate/t_java_generator.cc | 62 +++++++++++++++---- compiler/cpp/src/main.cc | 10 ++- compiler/cpp/src/parse/t_const_value.h | 30 ++++++++- 3 files changed, 82 insertions(+), 20 deletions(-) diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc index 7acd9aca..b6223226 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -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& members = tstruct->get_members(); vector::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 { diff --git a/compiler/cpp/src/main.cc b/compiler/cpp/src/main.cc index fa6d3aee..0c561b9c 100644 --- a/compiler/cpp/src/main.cc +++ b/compiler/cpp/src/main.cc @@ -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& enum_values = ((t_enum*)type)->get_constants(); vector::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 43c28b10..ff422ae4 100644 --- a/compiler/cpp/src/parse/t_const_value.h +++ b/compiler/cpp/src/parse/t_const_value.h @@ -24,6 +24,7 @@ #include #include #include +#include /** * 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; } -- 2.17.1