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