void t_java_deprecated_generator::generate_java_struct_reader()

in thrift/compiler/generate/t_java_deprecated_generator.cc [1579:1725]


void t_java_deprecated_generator::generate_java_struct_reader(
    ofstream& out, const t_struct* tstruct) {
  if (generate_immutable_structs_) {
    out << indent()
        << "// This is required to satisfy the TBase interface, but can't be implemented on immutable struture."
        << endl;
    out << indent() << "public void read(TProtocol iprot) throws TException {"
        << endl;
    out << indent()
        << "  throw new TException(\"unimplemented in android immutable structure\");"
        << endl;
    out << indent() << "}" << endl << endl;

    out << indent() << "public static " << tstruct->get_name()
        << " deserialize(TProtocol iprot) throws TException {" << endl;
    indent_up();
  } else {
    out << indent() << "public void read(TProtocol iprot) throws TException {"
        << endl;
    indent_up();
  }

  const vector<t_field*>& fields = tstruct->get_members();
  vector<t_field*>::const_iterator f_iter;

  if (generate_immutable_structs_) {
    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
      string tmp_name = "tmp_" + (*f_iter)->get_name();
      const t_type* field_type = (*f_iter)->get_type();
      indent(out) << type_name(field_type) << " " << tmp_name;
      if (type_can_be_null(field_type)) {
        out << " = null";
      } else if (
          field_type->is_any_int() || field_type->is_double() ||
          field_type->is_float()) {
        out << " = 0";
      } else if (field_type->is_bool()) {
        out << " = false";
      }
      out << ";" << endl;
    }
  }

  // Declare stack tmp variables and read struct header
  out << indent() << "TField __field;" << endl
      << indent() << "iprot.readStructBegin("
      << (generate_field_metadata_ ? "metaDataMap" : "") << ");" << endl;

  // Loop over reading in fields
  indent(out) << "while (true)" << endl;
  scope_up(out);

  // Read beginning field marker
  indent(out) << "__field = iprot.readFieldBegin();" << endl;

  // Check for field STOP marker and break
  indent(out) << "if (__field.type == TType.STOP) {" << endl;
  indent_up();
  indent(out) << "break;" << endl;
  indent_down();
  indent(out) << "}" << endl;

  // Switch statement on the field we are reading
  indent(out) << "switch (__field.id)" << endl;

  scope_up(out);

  // Generate deserialization code for known cases
  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
    indent(out) << "case " << upcase_string((*f_iter)->get_name()) << ":"
                << endl;
    indent_up();
    indent(out) << "if (__field.type == " << type_to_enum((*f_iter)->get_type())
                << ") {" << endl;
    indent_up();

    if (generate_immutable_structs_) {
      generate_deserialize_field(out, *f_iter, "tmp_");
    } else {
      generate_deserialize_field(out, *f_iter, "this.");
      generate_isset_set(out, *f_iter);
    }
    indent_down();
    out << indent() << "} else {" << endl
        << indent() << "  TProtocolUtil.skip(iprot, __field.type);" << endl
        << indent() << "}" << endl
        << indent() << "break;" << endl;
    indent_down();
  }

  // In the default case we skip the field
  out << indent() << "default:" << endl
      << indent() << "  TProtocolUtil.skip(iprot, __field.type);" << endl
      << indent() << "  break;" << endl;

  scope_down(out);

  // Read field end marker
  indent(out) << "iprot.readFieldEnd();" << endl;

  scope_down(out);

  out << indent() << "iprot.readStructEnd();" << endl << endl;

  if (generate_immutable_structs_) {
    indent(out) << tstruct->get_name() << " _that;" << endl;
    indent(out) << "_that = new " << tstruct->get_name() << "(" << endl;
    bool first = true;
    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
      string tmp_name = "tmp_" + (*f_iter)->get_name();
      if (first) {
        indent(out) << "  " << tmp_name << endl;
      } else {
        indent(out) << "  ," << tmp_name << endl;
      }
      first = false;
    }
    indent(out) << ");" << endl;
    indent(out) << "_that.validate();" << endl;
    indent(out) << "return _that;" << endl;
  } else {
    // Check for required fields of primitive type
    // (which can be checked here but not in the general validate method)
    out << endl
        << indent()
        << "// check for required fields of primitive type, which can't be checked in the validate method"
        << endl;
    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
      if ((*f_iter)->get_req() == t_field::e_req::required &&
          !type_can_be_null((*f_iter)->get_type())) {
        out << indent() << "if (!" << generate_isset_check(*f_iter) << ") {"
            << endl
            << indent() << "  throw new TProtocolException(\"Required field '"
            << (*f_iter)->get_name()
            << "' was not found in serialized data! Struct: \" + toString());"
            << endl
            << indent() << "}" << endl;
      }
    }

    // performs various checks (e.g. check that all required fields are set)
    indent(out) << "validate();" << endl;
  }

  indent_down();
  out << indent() << "}" << endl << endl;
}