void t_java_deprecated_generator::generate_java_struct_definition()

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;
}