in compiler/cpp/src/thrift/generate/t_js_generator.cc [697:805]
string t_js_generator::render_const_value(t_type* type, t_const_value* value) {
std::ostringstream out;
type = get_true_type(type);
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
switch (tbase) {
case t_base_type::TYPE_STRING:
out << "'" << get_escaped_string(value) << "'";
break;
case t_base_type::TYPE_BOOL:
out << (value->get_integer() > 0 ? "true" : "false");
break;
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
out << value->get_integer();
break;
case t_base_type::TYPE_I64:
{
int64_t const& integer_value = value->get_integer();
if (integer_value <= max_safe_integer && integer_value >= min_safe_integer) {
out << "new Int64(" << integer_value << ")";
} else {
out << "new Int64('" << std::hex << integer_value << std::dec << "')";
}
}
break;
case t_base_type::TYPE_DOUBLE:
if (value->get_type() == t_const_value::CV_INTEGER) {
out << value->get_integer();
} else {
out << emit_double_as_string(value->get_double());
}
break;
default:
throw std::runtime_error("compiler error: no const of base type " + t_base_type::t_base_name(tbase));
}
} else if (type->is_enum()) {
out << value->get_integer();
} else if (type->is_struct() || type->is_xception()) {
out << "new " << js_type_namespace(type->get_program()) << type->get_name() << "({";
indent_up();
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = nullptr;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if ((*f_iter)->get_name() == v_iter->first->get_string()) {
field_type = (*f_iter)->get_type();
}
}
if (field_type == nullptr) {
throw std::runtime_error("type error: " + type->get_name() + " has no field " + v_iter->first->get_string());
}
if (v_iter != val.begin())
out << ",";
out << '\n' << indent() << render_const_value(g_type_string, v_iter->first);
out << " : ";
out << render_const_value(field_type, v_iter->second);
}
indent_down();
out << '\n' << indent() << "})";
} else if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
out << "{" << '\n';
indent_up();
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
if (v_iter != val.begin())
out << "," << '\n';
if (ktype->is_base_type() && ((t_base_type*)get_true_type(ktype))->get_base() == t_base_type::TYPE_I64){
out << indent() << "\"" << v_iter->first->get_integer() << "\"";
} else {
out << indent() << render_const_value(ktype, v_iter->first);
}
out << " : ";
out << render_const_value(vtype, v_iter->second);
}
indent_down();
out << '\n' << indent() << "}";
} else if (type->is_list() || type->is_set()) {
t_type* etype;
if (type->is_list()) {
etype = ((t_list*)type)->get_elem_type();
} else {
etype = ((t_set*)type)->get_elem_type();
}
out << "[";
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
if (v_iter != val.begin())
out << ",";
out << render_const_value(etype, *v_iter);
}
out << "]";
}
return out.str();
}