in compiler/cpp/src/thrift/generate/t_js_generator.cc [891:1100]
void t_js_generator::generate_js_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception,
bool is_exported) {
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
if (gen_node_) {
string commonjs_export = "";
if (is_exported) {
if (gen_esm_) {
out << "export ";
} else {
commonjs_export = " = module.exports." + tstruct->get_name();
}
}
string prefix = has_js_namespace(tstruct->get_program()) ? js_namespace(tstruct->get_program()) : js_const_type_;
out << prefix << tstruct->get_name() << commonjs_export;
if (gen_ts_) {
f_types_ts_ << ts_print_doc(tstruct) << ts_indent() << ts_declare() << "class "
<< tstruct->get_name() << (is_exception ? " extends Thrift.TException" : "")
<< " {" << '\n';
}
} else {
out << js_namespace(tstruct->get_program()) << tstruct->get_name();
if (gen_ts_) {
f_types_ts_ << ts_print_doc(tstruct) << ts_indent() << ts_declare() << "class "
<< tstruct->get_name() << (is_exception ? " extends Thrift.TException" : "")
<< " {" << '\n';
}
}
if (gen_es6_) {
if (gen_node_ && is_exception) {
out << " = class extends Thrift.TException {" << '\n';
} else {
out << " = class {" << '\n';
}
indent_up();
indent(out) << "constructor(args) {" << '\n';
} else {
out << " = function(args) {" << '\n';
}
indent_up();
// Call super() method on inherited Error class
if (gen_node_ && is_exception) {
if (gen_es6_) {
indent(out) << "super(args);" << '\n';
} else {
indent(out) << "Thrift.TException.call(this, \"" << js_namespace(tstruct->get_program())
<< tstruct->get_name() << "\");" << '\n';
}
out << indent() << "this.name = \"" << js_namespace(tstruct->get_program())
<< tstruct->get_name() << "\";" << '\n';
}
// members with arguments
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
string dval = declare_field(*m_iter, false, true);
t_type* t = get_true_type((*m_iter)->get_type());
if ((*m_iter)->get_value() != nullptr && !(t->is_struct() || t->is_xception())) {
dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value());
out << indent() << "this." << (*m_iter)->get_name() << " = " << dval << ";" << '\n';
} else {
out << indent() << dval << ";" << '\n';
}
if (gen_ts_) {
string ts_access = gen_node_ ? "public " : "";
string member_name = (*m_iter)->get_name();
// Special case. Exceptions derive from Error, and error has a non optional message field.
// Ignore the optional flag in this case, otherwise we will generate a incompatible field
// in the eyes of typescript.
string optional_flag = is_exception && member_name == "message" ? "" : ts_get_req(*m_iter);
f_types_ts_ << ts_indent() << ts_access << member_name << optional_flag << ": "
<< ts_get_type((*m_iter)->get_type()) << ";" << '\n';
}
}
// Generate constructor from array
if (members.size() > 0) {
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
t_type* t = get_true_type((*m_iter)->get_type());
if ((*m_iter)->get_value() != nullptr && (t->is_struct() || t->is_xception())) {
indent(out) << "this." << (*m_iter)->get_name() << " = "
<< render_const_value(t, (*m_iter)->get_value()) << ";" << '\n';
}
}
// Early returns for exceptions
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
t_type* t = get_true_type((*m_iter)->get_type());
if (t->is_xception()) {
out << indent() << "if (args instanceof " << js_type_namespace(t->get_program())
<< t->get_name() << ") {" << '\n' << indent() << indent() << "this."
<< (*m_iter)->get_name() << " = args;" << '\n' << indent() << indent() << "return;"
<< '\n' << indent() << "}" << '\n';
}
}
indent(out) << "if (args) {" << '\n';
indent_up();
if (gen_ts_) {
f_types_ts_ << '\n' << ts_indent() << "constructor(args?: { ";
}
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
t_type* t = get_true_type((*m_iter)->get_type());
indent(out) << "if (args." << (*m_iter)->get_name() << " !== undefined && args." << (*m_iter)->get_name() << " !== null) {" << '\n';
indent_up();
indent(out) << "this." << (*m_iter)->get_name();
if (t->is_struct()) {
out << (" = new " + js_type_namespace(t->get_program()) + t->get_name() +
"(args."+(*m_iter)->get_name() +");");
out << '\n';
} else if (t->is_container()) {
t_type* etype = get_contained_type(t);
string copyFunc = t->is_map() ? "Thrift.copyMap" : "Thrift.copyList";
string type_list = "";
while (etype->is_container()) {
if (type_list.length() > 0) {
type_list += ", ";
}
type_list += etype->is_map() ? "Thrift.copyMap" : "Thrift.copyList";
etype = get_contained_type(etype);
}
if (etype->is_struct()) {
if (type_list.length() > 0) {
type_list += ", ";
}
type_list += js_type_namespace(etype->get_program()) + etype->get_name();
}
else {
if (type_list.length() > 0) {
type_list += ", ";
}
type_list += "null";
}
out << (" = " + copyFunc + "(args." + (*m_iter)->get_name() +
", [" + type_list + "]);");
out << '\n';
} else {
out << " = args." << (*m_iter)->get_name() << ";" << '\n';
}
indent_down();
if (!(*m_iter)->get_req()) {
indent(out) << "} else {" << '\n';
indent(out)
<< " throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, "
"'Required field " << (*m_iter)->get_name() << " is unset!');" << '\n';
}
indent(out) << "}" << '\n';
if (gen_ts_) {
f_types_ts_ << (*m_iter)->get_name() << ts_get_req(*m_iter) << ": "
<< ts_get_type((*m_iter)->get_type()) << "; ";
}
}
indent_down();
out << indent() << "}" << '\n';
if (gen_ts_) {
f_types_ts_ << "});" << '\n';
}
}
// Done with constructor
indent_down();
if (gen_es6_) {
indent(out) << "}" << '\n' << '\n';
} else {
indent(out) << "};" << '\n';
}
if (gen_ts_) {
f_types_ts_ << ts_indent() << "}" << '\n';
}
if (!gen_es6_) {
if (is_exception) {
out << "Thrift.inherits(" << js_namespace(tstruct->get_program()) << tstruct->get_name()
<< ", Thrift.TException);" << '\n';
out << js_namespace(tstruct->get_program()) << tstruct->get_name() << ".prototype.name = '"
<< tstruct->get_name() << "';" << '\n';
} else {
// init prototype manually if we aren't using es6
out << js_namespace(tstruct->get_program()) << tstruct->get_name() << ".prototype = {};"
<< '\n';
}
}
generate_js_struct_reader(out, tstruct);
generate_js_struct_writer(out, tstruct);
// Close out the class definition
if (gen_es6_) {
indent_down();
indent(out) << "};" << '\n';
}
}