Add include_once statements for generated PHP code that depends upon other types
Reviewed By: root
Test Plan: Generate PHP code for a .thrift file with an include in it
Other Notes: Reviewed by Todd Lipcon from AmieStreet
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665325 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc
index ba0e189..2fb4e18 100644
--- a/compiler/cpp/src/generate/t_php_generator.cc
+++ b/compiler/cpp/src/generate/t_php_generator.cc
@@ -32,6 +32,14 @@
autogen_comment() <<
php_includes();
+ // Include other Thrift includes
+ const vector<t_program*>& includes = program_->get_includes();
+ for (size_t i = 0; i < includes.size(); ++i) {
+ f_types_ <<
+ "include_once $GLOBALS['THRIFT_ROOT'].'/packages/" + includes[i]->get_name() << "_types.php';" << endl;
+ }
+ f_types_ << endl;
+
// Print header
f_consts_ <<
"<?php" << endl <<
@@ -78,7 +86,7 @@
void t_php_generator::generate_enum(t_enum* tenum) {
f_types_ <<
"$GLOBALS['" << php_namespace(tenum->get_program()) << "E_" << tenum->get_name() << "'] = array(" << endl;
-
+
vector<t_enum_value*> constants = tenum->get_constants();
vector<t_enum_value*>::iterator c_iter;
int value = -1;
@@ -103,7 +111,7 @@
f_types_ <<
"final class " << php_namespace(tenum->get_program()) << tenum->get_name() << " {" << endl;
indent_up();
-
+
value = -1;
for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
if ((*c_iter)->has_value()) {
@@ -143,8 +151,8 @@
t_type* type = tconst->get_type();
string name = tconst->get_name();
t_const_value* value = tconst->get_value();
-
- f_consts_ << "$GLOBALS['" << program_name_ << "_CONSTANTS']['" << name << "'] = ";
+
+ f_consts_ << "$GLOBALS['" << program_name_ << "_CONSTANTS']['" << name << "'] = ";
f_consts_ << render_const_value(type, value);
f_consts_ << ";" << endl << endl;
}
@@ -264,7 +272,7 @@
* @param txception The struct definition
*/
void t_php_generator::generate_xception(t_struct* txception) {
- generate_php_struct(txception, true);
+ generate_php_struct(txception, true);
}
/**
@@ -286,7 +294,7 @@
t_struct* tstruct,
bool is_exception) {
const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
+ vector<t_field*>::const_iterator m_iter;
out <<
"class " << php_namespace(tstruct->get_program()) << tstruct->get_name();
@@ -306,7 +314,7 @@
indent(out) <<
"public $" << (*m_iter)->get_name() << " = " << dval << ";" << endl;
}
-
+
out << endl;
// Generate constructor from array
@@ -321,7 +329,7 @@
indent(out) << "$this->" << (*m_iter)->get_name() << " = " << render_const_value(t, (*m_iter)->get_value()) << ";" << endl;
}
}
-
+
out <<
indent() << "if (is_array($vals)) {" << endl;
indent_up();
@@ -339,13 +347,13 @@
indent() << "}" << endl <<
endl;
}
-
+
out <<
indent() << "public function getName() {" << endl <<
indent() << " return '" << tstruct->get_name() << "';" << endl <<
indent() << "}" << endl <<
endl;
-
+
generate_php_struct_reader(out, tstruct);
generate_php_struct_writer(out, tstruct);
@@ -376,7 +384,7 @@
// Declare stack tmp variables
if (!binary_inline_) {
indent(out) <<
- "$xfer += $input->readStructBegin($fname);" << endl;
+ "$xfer += $input->readStructBegin($fname);" << endl;
}
// Loop over reading in fields
@@ -384,7 +392,7 @@
"while (true)" << endl;
scope_up(out);
-
+
// Read beginning field marker
if (binary_inline_) {
t_field fftype(g_type_byte, "ftype");
@@ -393,7 +401,7 @@
out <<
indent() << "if ($ftype == TType::STOP) {" << endl <<
indent() << " break;" << endl <<
- indent() << "}" << endl;
+ indent() << "}" << endl;
generate_deserialize_field(out, &ffid);
} else {
indent(out) <<
@@ -407,14 +415,14 @@
indent_down();
indent(out) <<
"}" << endl;
- }
-
+ }
+
// Switch statement on the field we are reading
indent(out) <<
"switch ($fid)" << endl;
scope_up(out);
-
+
// Generate deserialization code for known cases
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
indent(out) <<
@@ -431,12 +439,12 @@
} else {
indent(out) << " $xfer += $input->skip($ftype);" << endl;
}
- out <<
+ out <<
indent() << "}" << endl <<
indent() << "break;" << endl;
indent_down();
}
-
+
// In the default case we skip the field
indent(out) << "default:" << endl;
if (binary_inline_) {
@@ -445,17 +453,17 @@
indent(out) << " $xfer += $input->skip($ftype);" << endl;
}
indent(out) << " break;" << endl;
-
+
scope_down(out);
-
+
if (!binary_inline_) {
// Read field end marker
indent(out) <<
"$xfer += $input->readFieldEnd();" << endl;
}
-
+
scope_down(out);
-
+
if (!binary_inline_) {
indent(out) <<
"$xfer += $input->readStructEnd();" << endl;
@@ -487,7 +495,7 @@
"public function write($output) {" << endl;
}
indent_up();
-
+
indent(out) <<
"$xfer = 0;" << endl;
@@ -496,7 +504,7 @@
"$xfer += $output->writeStructBegin('" << name << "');" << endl;
}
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
out <<
indent() << "if ($this->" << (*f_iter)->get_name() << " !== null) {" << endl;
indent_up();
@@ -567,7 +575,7 @@
f_service_ <<
"include_once $GLOBALS['THRIFT_ROOT'].'/packages/" << tservice->get_extends()->get_program()->get_name() << "/" << tservice->get_extends()->get_name() << ".php';" << endl;
}
-
+
f_service_ <<
endl;
@@ -579,7 +587,7 @@
generate_service_client(tservice);
generate_service_helpers(tservice);
generate_service_processor(tservice);
-
+
// Close service file
f_service_ << "?>" << endl;
f_service_.close();
@@ -593,7 +601,7 @@
void t_php_generator::generate_service_processor(t_service* tservice) {
// Generate the dispatch methods
vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
+ vector<t_function*>::iterator f_iter;
string extends = "";
string extends_processor = "";
@@ -650,7 +658,7 @@
// HOT: check for method implementation
f_service_ <<
- indent() << "$methodname = 'process_'.$fname;" << endl <<
+ indent() << "$methodname = 'process_'.$fname;" << endl <<
indent() << "if (!method_exists($this, $methodname)) {" << endl;
if (binary_inline_) {
f_service_ <<
@@ -724,7 +732,7 @@
indent() << "try {" << endl;
indent_up();
}
-
+
// Generate the function call
t_struct* arg_struct = tfunction->get_arglist();
const std::vector<t_field*>& fields = arg_struct->get_members();
@@ -858,7 +866,7 @@
"interface " << service_name_ << "If" << extends_if << " {" << endl;
indent_up();
vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
+ vector<t_function*>::iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
indent(f_service_) <<
"public function " << function_signature(*f_iter) << ";" << endl;
@@ -895,7 +903,7 @@
endl;
vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
+ vector<t_function*>::iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
indent(f_service_) <<
"public function " << (*f_iter)->get_name() << "($request) {" << endl;
@@ -910,16 +918,16 @@
indent() << "$" << (*a_iter)->get_name() << " = isset(" << req << ") ? " << cast << req << " : null;" << endl;
if (atype->is_string() &&
((t_base_type*)atype)->is_string_list()) {
- f_service_ <<
+ f_service_ <<
indent() << "$" << (*a_iter)->get_name() << " = explode(',', $" << (*a_iter)->get_name() << ");" << endl;
} else if (atype->is_map() || atype->is_list()) {
- f_service_ <<
+ f_service_ <<
indent() << "$" << (*a_iter)->get_name() << " = json_decode($" << (*a_iter)->get_name() << ", true);" << endl;
} else if (atype->is_set()) {
- f_service_ <<
+ f_service_ <<
indent() << "$" << (*a_iter)->get_name() << " = array_fill_keys(json_decode($" << (*a_iter)->get_name() << ", true), 1);" << endl;
} else if (atype->is_struct() || atype->is_xception()) {
- f_service_ <<
+ f_service_ <<
indent() << "$" << (*a_iter)->get_name() << " = new " << php_namespace(atype->get_program()) << atype->get_name() << "(json_decode($" << (*a_iter)->get_name() << ", true));" << endl;
}
}
@@ -932,7 +940,7 @@
}
indent_down();
f_service_ <<
- "}" << endl << endl;
+ "}" << endl << endl;
}
/**
@@ -975,11 +983,11 @@
indent() << " $this->output_ = $output ? $output : $input;" << endl;
}
f_service_ <<
- indent() << "}" << endl << endl;
+ indent() << "}" << endl << endl;
// Generate client method implementations
vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::const_iterator f_iter;
+ vector<t_function*>::const_iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
t_struct* arg_struct = (*f_iter)->get_arglist();
const vector<t_field*>& fields = arg_struct->get_members();
@@ -1017,7 +1025,7 @@
indent(f_service_) <<
"public function send_" << function_signature(*f_iter) << endl;
- scope_up(f_service_);
+ scope_up(f_service_);
std::string argsname = php_namespace(tservice->get_program()) + service_name_ + "_" + (*f_iter)->get_name() + "_args";
@@ -1032,17 +1040,17 @@
f_service_ <<
indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType::CALL, $this->seqid_);" << endl;
}
-
+
f_service_ <<
indent() << "$args = new " << argsname << "();" << endl;
-
+
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
f_service_ <<
indent() << "$args->" << (*fld_iter)->get_name() << " = $" << (*fld_iter)->get_name() << ";" << endl;
}
-
+
// Write to the stream
- if (binary_inline_) {
+ if (binary_inline_) {
f_service_ <<
indent() << "$args->write($buff);" << endl <<
indent() << "$this->output_->write($buff);" << endl <<
@@ -1052,15 +1060,15 @@
indent() << "$args->write($this->output_);" << endl <<
indent() << "$this->output_->writeMessageEnd();" << endl <<
indent() << "$this->output_->getTransport()->flush();" << endl;
- }
-
+ }
+
scope_down(f_service_);
-
+
if (!(*f_iter)->is_async()) {
std::string resultname = php_namespace(tservice->get_program()) + service_name_ + "_" + (*f_iter)->get_name() + "_result";
t_struct noargs(program_);
-
+
t_function recv_function((*f_iter)->get_returntype(),
string("recv_") + (*f_iter)->get_name(),
&noargs);
@@ -1133,13 +1141,13 @@
} else {
f_service_ <<
indent() << "throw new Exception(\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
- }
+ }
// Close function
scope_down(f_service_);
f_service_ << endl;
- }
+ }
}
indent_down();
@@ -1189,7 +1197,7 @@
indent_down();
out << indent() << "} else {" << endl;
indent_up();
-
+
if (binary_inline_) {
std::string itrans = (inclass ? "$this->input_" : "$input");
@@ -1270,7 +1278,7 @@
indent(out) <<
"$xfer += $input->";
-
+
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
switch (tbase) {
@@ -1278,7 +1286,7 @@
throw "compiler error: cannot serialize void field in a struct: " +
name;
break;
- case t_base_type::TYPE_STRING:
+ case t_base_type::TYPE_STRING:
out << "readString($" << name << ");";
break;
case t_base_type::TYPE_BOOL:
@@ -1356,12 +1364,12 @@
scope_down(out);
out << indent() << "else" << endl;
scope_up(out);
-
+
string size = tmp("_size");
string ktype = tmp("_ktype");
string vtype = tmp("_vtype");
string etype = tmp("_etype");
-
+
t_field fsize(g_type_i32, size);
t_field fktype(g_type_byte, ktype);
t_field fvtype(g_type_byte, vtype);
@@ -1370,7 +1378,7 @@
out <<
indent() << "$" << prefix << " = array();" << endl <<
indent() << "$" << size << " = 0;" << endl;
-
+
// Declare variables, read header
if (ttype->is_map()) {
out <<
@@ -1412,9 +1420,9 @@
indent(out) <<
"for ($" <<
i << " = 0; $" << i << " < $" << size << "; ++$" << i << ")" << endl;
-
+
scope_up(out);
-
+
if (ttype->is_map()) {
generate_deserialize_map_element(out, (t_map*)ttype, prefix);
} else if (ttype->is_set()) {
@@ -1422,7 +1430,7 @@
} else if (ttype->is_list()) {
generate_deserialize_list_element(out, (t_list*)ttype, prefix);
}
-
+
scope_down(out);
if (!binary_inline_) {
@@ -1510,7 +1518,7 @@
throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " +
prefix + tfield->get_name();
}
-
+
if (type->is_struct() || type->is_xception()) {
generate_serialize_struct(out,
(t_struct*)type,
@@ -1553,11 +1561,11 @@
indent() << "$output .= pack('N', $" << name << ");" << endl;
break;
case t_base_type::TYPE_I64:
- out <<
+ out <<
indent() << "$output .= pack('N2', $" << name << " >> 32, $" << name << " & 0xFFFFFFFF);" << endl;
break;
case t_base_type::TYPE_DOUBLE:
- out <<
+ out <<
indent() << "$output .= strrev(pack('d', $" << name << "));" << endl;
break;
default:
@@ -1571,7 +1579,7 @@
indent(out) <<
"$xfer += $output->";
-
+
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
switch (tbase) {
@@ -1626,7 +1634,7 @@
t_struct* tstruct,
string prefix) {
indent(out) <<
- "$xfer += $" << prefix << "->write($output);" << endl;
+ "$xfer += $" << prefix << "->write($output);" << endl;
}
/**
@@ -1636,7 +1644,7 @@
t_type* ttype,
string prefix) {
scope_up(out);
-
+
if (ttype->is_map()) {
if (binary_inline_) {
out <<
@@ -1681,28 +1689,28 @@
if (ttype->is_map()) {
string kiter = tmp("kiter");
string viter = tmp("viter");
- indent(out) <<
+ indent(out) <<
"foreach ($" << prefix << " as " <<
"$" << kiter << " => $" << viter << ")" << endl;
- scope_up(out);
+ scope_up(out);
generate_serialize_map_element(out, (t_map*)ttype, kiter, viter);
scope_down(out);
} else if (ttype->is_set()) {
string iter = tmp("iter");
- indent(out) <<
+ indent(out) <<
"foreach ($" << prefix << " as $" << iter << " => $true)" << endl;
scope_up(out);
generate_serialize_set_element(out, (t_set*)ttype, iter);
scope_down(out);
} else if (ttype->is_list()) {
string iter = tmp("iter");
- indent(out) <<
+ indent(out) <<
"foreach ($" << prefix << " as $" << iter << ")" << endl;
scope_up(out);
generate_serialize_list_element(out, (t_list*)ttype, iter);
scope_down(out);
}
-
+
scope_down(out);
if (!binary_inline_) {
@@ -1717,8 +1725,8 @@
"$output->writeListEnd();" << endl;
}
}
-
- scope_down(out);
+
+ scope_down(out);
}
/**
@@ -1868,7 +1876,7 @@
*/
string t_php_generator ::type_to_enum(t_type* type) {
type = get_true_type(type);
-
+
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
switch (tbase) {