void t_hack_generator::generate_php_struct_constructor_field_assignment()

in thrift/compiler/generate/t_hack_generator.cc [3697:3777]


void t_hack_generator::generate_php_struct_constructor_field_assignment(
    std::ofstream& out,
    const t_field& field,
    const t_struct* tstruct,
    ThriftStructType type,
    const std::string& name,
    bool is_default_assignment) {
  const t_type* t = field.type()->get_true_type();
  const auto true_type = type_to_typehint(t, false, false, false, false);
  std::string dval = "";
  bool is_exception = tstruct->is_exception();
  if (field.default_value() != nullptr &&
      !(t->is_struct() || t->is_xception())) {
    dval = render_const_value(t, field.default_value());
  } else if (
      tstruct->is_exception() &&
      (field.name() == "code" || field.name() == "line")) {
    if (t->is_any_int()) {
      dval = "0";
    } else {
      // just use the lowest value
      const t_enum* tenum = static_cast<const t_enum*>(t);
      dval =
          hack_name(tenum) + "::" + (*tenum->get_enum_values().begin())->name();
    }
  } else if (
      is_exception && (field.name() == "message" || field.name() == "file")) {
    dval = "''";
  } else if (tstruct->is_union() || nullable_everything_) {
    dval = "null";
  } else {
    dval = render_default_value(t);
  }
  if (dval != "null") {
    if (const auto* adapter = find_hack_adapter(field.get_type())) {
      dval = *adapter + "::fromThrift(" + dval + ")";
    }
  }

  // result structs only contain fields: success and e.
  // success is whatever type the method returns, but must be nullable
  // regardless, since if there is an exception we expect it to be null
  // TODO(ckwalsh) Extract this logic into a helper function
  bool nullable = type == ThriftStructType::RESULT ||
      (!(is_exception && is_base_exception_property(&field)) &&
       (dval == "null" ||
        (field.get_req() == t_field::e_req::optional &&
         field.default_value() == nullptr)));

  const std::string& field_name = field.name();
  bool need_enum_code_fixme = is_exception && field_name == "code" &&
      t->is_enum() && !enum_transparenttype_;
  if (is_default_assignment) {
    if (const auto* field_wrapper = find_hack_wrapper(field)) {
      out << indent() << "$this->" << field_name << " = " << *field_wrapper
          << "::fromThrift_DO_NOT_USE_THRIFT_INTERNAL<" << (nullable ? "?" : "")
          << true_type << ", " << hack_name(name, tstruct->program(), true)
          << ">(" << (nullable ? "null" : dval) << ", " << field.get_key()
          << ", $this);\n";
    } else if (!nullable) {
      out << indent() << "$this->" << field_name << " = " << dval << ";\n";
    }
  } else {
    if (tstruct->is_union()) {
      // Capture value from constructor and update _type field
      out << indent() << "if ($" << field_name << " !== null) {\n";
    }
    if (need_enum_code_fixme) {
      out << indent() << "  /* HH_FIXME[4110] nontransparent Enum */\n";
    }
    out << indent() << (tstruct->is_union() ? "  " : "") << "$this->"
        << field_name << " = $" << field_name
        << (!nullable ? " ?? " + dval : "") << ";\n";
    if (tstruct->is_union()) {
      out << indent()
          << "  $this->_type = " << union_field_to_enum(tstruct, &field, name)
          << ";\n"
          << indent() << "}\n";
    }
  }
}