void t_java_generator::generate_java_struct_definition()

in compiler/cpp/src/thrift/generate/t_java_generator.cc [1529:1792]


void t_java_generator::generate_java_struct_definition(ostream& out,
                                                       t_struct* tstruct,
                                                       bool is_exception,
                                                       bool in_class,
                                                       bool is_result) {
  generate_java_doc(out, tstruct);
  indent(out) << java_suppressions();

  bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end());
  bool is_deprecated = this->is_deprecated(tstruct->annotations_);

  if (!in_class && !suppress_generated_annotations_) {
    generate_javax_generated_annotation(out);
  }

  if (is_deprecated) {
    indent(out) << "@Deprecated" << '\n';
  }
  indent(out) << "public " << (is_final ? "final " : "") << (in_class ? "static " : "") << "class "
              << make_valid_java_identifier(tstruct->get_name()) << " ";

  if (is_exception) {
    out << "extends org.apache.thrift.TException ";
  }
  out << "implements org.apache.thrift.TBase<" << make_valid_java_identifier(tstruct->get_name())
      << ", " << make_valid_java_identifier(tstruct->get_name())
      << "._Fields>, java.io.Serializable, Cloneable, Comparable<" << make_valid_java_identifier(tstruct->get_name()) << ">";

  if (android_style_) {
    out << ", android.os.Parcelable";
  }

  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;

  out << '\n';

  generate_field_descs(out, tstruct);

  out << '\n';

  generate_scheme_map(out, tstruct);

  out << '\n';

  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
    if (bean_style_ || private_members_) {
      indent(out) << "private ";
    } else {
      generate_java_doc(out, *m_iter);
      indent(out) << "public ";
    }
    out << declare_field(*m_iter, false, true) << '\n';
  }

  out << '\n';

  if (android_style_) {
    generate_java_struct_parcelable(out, tstruct);
  }

  generate_field_name_constants(out, tstruct);

  // isset data
  if (members.size() > 0) {
    out << '\n';

    indent(out) << "// isset id assignments" << '\n';

    int i = 0;
    int optionals = 0;
    for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
      if ((*m_iter)->get_req() == t_field::T_OPTIONAL) {
        optionals++;
      }
      if (!type_can_be_null((*m_iter)->get_type())) {
        indent(out) << "private static final int " << isset_field_id(*m_iter) << " = " << i << ";"
                    << '\n';
        i++;
      }
    }

    std::string primitiveType;
    switch (needs_isset(tstruct, &primitiveType)) {
    case ISSET_NONE:
      break;
    case ISSET_PRIMITIVE:
      indent(out) << "private " << primitiveType << " __isset_bitfield = 0;" << '\n';
      break;
    case ISSET_BITSET:
      indent(out) << "private java.util.BitSet __isset_bit_vector = new java.util.BitSet(" << i
                  << ");" << '\n';
      break;
    }

    if (optionals > 0) {
      std::string output_string = "private static final _Fields[] optionals = {";
      for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
        if ((*m_iter)->get_req() == t_field::T_OPTIONAL) {
          output_string = output_string + "_Fields." + constant_name((*m_iter)->get_name()) + ",";
        }
      }
      indent(out) << output_string.substr(0, output_string.length() - 1) << "};" << '\n';
    }
  }

  generate_java_meta_data_map(out, tstruct);

  bool all_optional_members = true;

  // Default constructor
  indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "() {" << '\n';
  indent_up();
  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
    t_type* t = get_true_type((*m_iter)->get_type());
    if ((*m_iter)->get_value() != nullptr) {
      print_const_value(out, "this." + (*m_iter)->get_name(), t, (*m_iter)->get_value(), true,
                        true);
    }
    if ((*m_iter)->get_req() != t_field::T_OPTIONAL) {
      all_optional_members = false;
    }
  }
  indent_down();
  indent(out) << "}" << '\n' << '\n';

  if (!members.empty() && !all_optional_members) {
    // Full constructor for all fields
    indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << "(" << '\n';
    indent_up();
    bool first = true;
    for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
      if ((*m_iter)->get_req() != t_field::T_OPTIONAL) {
        if (!first) {
          out << "," << '\n';
        }
        first = false;
        indent(out) << type_name((*m_iter)->get_type()) << " " << make_valid_java_identifier((*m_iter)->get_name());
      }
    }
    out << ")" << '\n';
    indent_down();
    indent(out) << "{" << '\n';
    indent_up();
    indent(out) << "this();" << '\n';
    for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
      if ((*m_iter)->get_req() != t_field::T_OPTIONAL) {
        t_type* type = get_true_type((*m_iter)->get_type());
        if (type->is_binary()) {
          if (unsafe_binaries_) {
            indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name())
                        << " = " << make_valid_java_identifier((*m_iter)->get_name()) << ";"
                        << '\n';
          } else {
            indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name())
                        << " = org.apache.thrift.TBaseHelper.copyBinary("
                        << make_valid_java_identifier((*m_iter)->get_name())
                        << ");" << '\n';
          }
        } else {
          indent(out) << "this." << make_valid_java_identifier((*m_iter)->get_name()) << " = "
                      << make_valid_java_identifier((*m_iter)->get_name()) << ";"
                      << '\n';
        }
        generate_isset_set(out, (*m_iter), "");
      }
    }

    indent_down();
    indent(out) << "}" << '\n' << '\n';
  }

  // copy constructor
  indent(out) << "/**" << '\n';
  indent(out) << " * Performs a deep copy on <i>other</i>." << '\n';
  indent(out) << " */" << '\n';
  indent(out) << "public " << make_valid_java_identifier(tstruct->get_name())
              << "(" << make_valid_java_identifier(tstruct->get_name()) << " other) {"
              << '\n';
  indent_up();

  switch (needs_isset(tstruct)) {
  case ISSET_NONE:
    break;
  case ISSET_PRIMITIVE:
    indent(out) << "__isset_bitfield = other.__isset_bitfield;" << '\n';
    break;
  case ISSET_BITSET:
    indent(out) << "__isset_bit_vector.clear();" << '\n';
    indent(out) << "__isset_bit_vector.or(other.__isset_bit_vector);" << '\n';
    break;
  }

  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
    t_field* field = (*m_iter);
    std::string field_name = field->get_name();
    t_type* type = field->get_type()->get_true_type();
    bool can_be_null = type_can_be_null(type);

    if (can_be_null) {
      indent(out) << "if (other." << generate_isset_check(field) << ") {" << '\n';
      indent_up();
    }

    if (type->is_container()) {
      generate_deep_copy_container(out, "other", field_name, "__this__" + field_name, type);
      indent(out) << "this." << make_valid_java_identifier(field_name) << " = __this__" << field_name << ";" << '\n';
    } else {
      indent(out) << "this." << make_valid_java_identifier(field_name) << " = ";
      generate_deep_copy_non_container(out, "other." + make_valid_java_identifier(field_name), field_name, type);
      out << ";" << '\n';
    }

    if (can_be_null) {
      indent_down();
      indent(out) << "}" << '\n';
    }
  }

  indent_down();
  indent(out) << "}" << '\n' << '\n';

  // clone method, so that you can deep copy an object when you don't know its class.
  indent(out) << java_override_annotation() << '\n';
  indent(out) << "public " << make_valid_java_identifier(tstruct->get_name()) << " deepCopy() {" << '\n';
  indent(out) << "  return new " << make_valid_java_identifier(tstruct->get_name()) << "(this);" << '\n';
  indent(out) << "}" << '\n' << '\n';

  generate_java_struct_clear(out, tstruct);

  generate_java_bean_boilerplate(out, tstruct);
  generate_generic_field_getters_setters(out, tstruct);
  generate_generic_isset_method(out, tstruct);

  generate_java_struct_equality(out, tstruct);
  generate_java_struct_compare_to(out, tstruct);
  generate_java_struct_field_by_id(out, tstruct);

  generate_java_struct_reader(out, tstruct);
  if (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);

  generate_java_struct_write_object(out, tstruct);
  generate_java_struct_read_object(out, tstruct);

  generate_java_struct_standard_scheme(out, tstruct, is_result);
  generate_java_struct_tuple_scheme(out, tstruct);
  generate_java_scheme_lookup(out);

  scope_down(out);
  out << '\n';
}