void t_hack_generator::generate_php_struct_fields()

in thrift/compiler/generate/t_hack_generator.cc [3477:3573]


void t_hack_generator::generate_php_struct_fields(
    std::ofstream& out,
    const t_struct* tstruct,
    const std::string& struct_hack_name,
    ThriftStructType type) {
  auto struct_class_name =
      hack_name(struct_hack_name, tstruct->program(), true);
  for (const auto& field : tstruct->fields()) {
    bool is_base_exception_field = type == ThriftStructType::EXCEPTION &&
        is_base_exception_property(&field);

    const auto* field_wrapper = find_hack_wrapper(field);

    if (is_base_exception_field && field_wrapper) {
      throw std::runtime_error(
          tstruct->name() + "::" + field.name() +
          " has a wrapped type. FieldWrapper annotation is not allowed for base exception properties.");
    }

    const t_type* t = field.get_type();

    t = t->get_true_type();

    if (t->is_enum() && is_bitmask_enum(static_cast<const t_enum*>(t))) {
      throw std::runtime_error(
          "Enum " + t->name() +
          " is actually a bitmask, cannot generate a field of this enum type");
    }

    std::string dval;
    if (field.default_value() != nullptr &&
        !(t->is_struct() || t->is_xception())) {
      dval = render_const_value(t, field.default_value());
    } else {
      dval = render_default_value(t);
    }

    // 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
    bool nullable =
        (type == ThriftStructType::RESULT ||
         field_is_nullable(tstruct, &field, dval) || nullable_everything_) &&
        !is_base_exception_field;

    // Compute typehint before resolving typedefs to avoid missing any adapter
    // annotations.
    std::string typehint = field_to_typehint(
        field,
        struct_class_name,
        nullable && !tstruct->is_union() /* is_field_nullable */);

    if (nullable || field_wrapper) {
      typehint = "?" + typehint;
    }

    if (type != ThriftStructType::RESULT && type != ThriftStructType::ARGS) {
      generate_php_docstring(out, &field);
    }

    if (std::string const* field_attributes =
            field.find_annotation_or_null("hack.attributes")) {
      indent(out) << "<<" << *field_attributes << ">>\n";
    }

    if (type == ThriftStructType::EXCEPTION && field.name() == "code") {
      if (!(t->is_any_int() || t->is_enum())) {
        throw std::runtime_error(
            tstruct->name() + "::code defined to be a non-integral type. " +
            "code fields for Exception classes must be integral");
      } else if (
          t->is_enum() &&
          static_cast<const t_enum*>(t)->get_enum_values().empty()) {
        throw std::runtime_error(
            "Enum " + t->name() + " is the type for the code property of " +
            tstruct->name() + ", but it has no values.");
      }
      if (t->is_enum()) {
        typehint = "/* Originally defined as " + typehint + " */ int";
      }
    }

    std::string visibility = field_wrapper
        ? "private"
        : ((protected_unions_ && tstruct->is_union()) ? "protected" : "public");

    indent(out) << visibility << " " << typehint << " $" << field.name()
                << ";\n";
    generate_php_struct_field_methods(
        out, &field, type == ThriftStructType::EXCEPTION);

    if (field_wrapper) {
      generate_php_field_wrapper_methods(
          out, field, tstruct->is_union(), nullable, struct_class_name);
    }
  }
}