in thrift/compiler/generate/t_java_deprecated_generator.cc [1226:1439]
void t_java_deprecated_generator::generate_java_struct_definition(
ofstream& out, const t_struct* tstruct, StructGenParams params) {
generate_java_doc(out, tstruct);
bool is_final = tstruct->has_annotation("final");
indent(out) << (params.in_class ? string() : java_suppress_warnings_struct())
<< "public " << (is_final ? "final " : "")
<< (params.in_class ? "static " : "") << "class "
<< tstruct->get_name() << " ";
boost::optional<string> parent = java_struct_parent_class(tstruct, params);
if (parent) {
out << "extends " << *parent << " ";
}
out << "implements TBase, java.io.Serializable, Cloneable";
if (is_comparable(tstruct)) {
out << ", Comparable<" << type_name(tstruct) << ">";
}
out << " ";
scope_up(out);
generate_struct_desc(out, tstruct);
// Members are public for -java, private for -javabean
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
generate_field_descs(out, tstruct);
out << endl;
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
generate_java_doc(out, *m_iter);
indent(out) << "public ";
if (params.gen_immutable) {
out << "final ";
}
out << declare_field(*m_iter, false) << endl;
}
generate_field_name_constants(out, tstruct);
uint32_t bitset_size = 0;
if (!params.gen_immutable) {
// isset data
if (members.size() > 0) {
out << endl;
indent(out) << "// isset id assignments" << endl;
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if (!type_can_be_null((*m_iter)->get_type())) {
indent(out) << "private static final int " << isset_field_id(*m_iter)
<< " = " << bitset_size << ";" << endl;
bitset_size++;
}
}
if (bitset_size > 0) {
indent(out) << "private BitSet __isset_bit_vector = new BitSet("
<< bitset_size << ");" << endl;
}
out << endl;
}
if (generate_field_metadata_) {
generate_java_meta_data_map(out, tstruct);
// Static initializer to populate global class to struct metadata map
indent(out) << "static {" << endl;
indent_up();
indent(out) << "FieldMetaData.addStructMetaDataMap(" << type_name(tstruct)
<< ".class, metaDataMap);" << endl;
indent_down();
indent(out) << "}" << endl;
}
}
out << endl;
vector<t_field*> required_members;
vector<t_field*> non_optional_members;
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if ((*m_iter)->get_req() == t_field::e_req::required) {
required_members.push_back(*m_iter);
}
if ((*m_iter)->get_req() != t_field::e_req::optional) {
non_optional_members.push_back(*m_iter);
}
}
if (params.gen_immutable &&
members.size() <= MAX_NUM_JAVA_CONSTRUCTOR_PARAMS) {
// Constructor for all fields
generate_java_constructor(out, tstruct, members);
} else {
// Default constructor
indent(out) << "public " << tstruct->get_name() << "() {" << endl;
indent_up();
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
const t_type* t = (*m_iter)->get_type()->get_true_type();
if ((*m_iter)->get_value() != nullptr) {
print_const_value(
out,
"this." + (*m_iter)->get_name(),
t,
(*m_iter)->get_value(),
true,
true);
}
}
indent_down();
indent(out) << "}" << endl << endl;
if (!required_members.empty() &&
required_members.size() <= MAX_NUM_JAVA_CONSTRUCTOR_PARAMS) {
// Constructor for all required fields
generate_java_constructor(out, tstruct, required_members);
}
if (non_optional_members.size() > required_members.size() &&
non_optional_members.size() <= MAX_NUM_JAVA_CONSTRUCTOR_PARAMS) {
// Constructor for all non-optional fields
generate_java_constructor(out, tstruct, non_optional_members);
}
if (members.size() > non_optional_members.size() &&
members.size() <= MAX_NUM_JAVA_CONSTRUCTOR_PARAMS) {
// Constructor for all fields
generate_java_constructor(out, tstruct, members);
}
}
auto forceBuilderGeneration =
tstruct->has_annotation("android.generate_builder");
if (forceBuilderGeneration || params.gen_builder ||
members.size() > MAX_NUM_JAVA_CONSTRUCTOR_PARAMS) {
generate_java_constructor_using_builder(
out, tstruct, members, bitset_size, !params.gen_immutable);
}
// copy constructor
indent(out) << "/**" << endl;
indent(out) << " * Performs a deep copy on <i>other</i>." << endl;
indent(out) << " */" << endl;
indent(out) << "public " << tstruct->get_name() << "(" << tstruct->get_name()
<< " other) {" << endl;
indent_up();
if (!params.gen_immutable && has_bit_vector(tstruct)) {
indent(out) << "__isset_bit_vector.clear();" << endl;
indent(out) << "__isset_bit_vector.or(other.__isset_bit_vector);" << endl;
}
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
const t_field* field = (*m_iter);
std::string field_name = field->get_name();
const t_type* type = field->get_type();
bool can_be_null = type_can_be_null(type);
if (can_be_null) {
indent(out) << "if (other." << generate_isset_check(field) << ") {"
<< endl;
indent_up();
}
indent(out) << "this." << field_name << " = TBaseHelper.deepCopy(other."
<< field_name << ");" << endl;
if (can_be_null) {
indent_down();
if (params.gen_immutable) {
indent(out) << "} else {" << endl;
indent(out) << " this." << field_name << " = null;" << endl;
}
indent(out) << "}" << endl;
}
}
indent_down();
indent(out) << "}" << endl << endl;
// clone method, so that you can deep copy an object when you don't know its
// class.
indent(out) << "public " << tstruct->get_name() << " deepCopy() {" << endl;
indent(out) << " return new " << tstruct->get_name() << "(this);" << endl;
indent(out) << "}" << endl << endl;
generate_java_bean_boilerplate(out, tstruct, params.gen_immutable);
generate_generic_field_getters_setters(out, tstruct);
generate_java_struct_equality(out, tstruct);
if (is_comparable(tstruct)) {
generate_java_struct_compare_to(out, tstruct);
}
generate_java_struct_reader(out, tstruct);
if (params.is_result) {
generate_java_struct_result_writer(out, tstruct);
} else {
generate_java_struct_writer(out, tstruct);
}
generate_java_struct_tostring(out, tstruct);
generate_java_validator(out, tstruct);
scope_down(out);
out << endl;
}