THRIFT-2859 JSON generator: output complete descriptors
Client: JSON
Patch: Stig Bakken <stig@zedge.net>
This closes #290
- add --gen json:merge option, and disable merging by default
- output complete descriptors
- add schema for JSON generator
- indent output
diff --git a/compiler/cpp/src/generate/t_json_generator.cc b/compiler/cpp/src/generate/t_json_generator.cc
index dee1de2..777a8b7 100644
--- a/compiler/cpp/src/generate/t_json_generator.cc
+++ b/compiler/cpp/src/generate/t_json_generator.cc
@@ -42,6 +42,8 @@
static const string endl = "\n";
static const string quot = "\"";
+static const bool NO_INDENT = false;
+static const bool FORCE_STRING = true;
class t_json_generator : public t_generator {
public:
@@ -52,6 +54,11 @@
(void)parsed_options;
(void)option_string;
out_dir_base_ = "gen-json";
+
+ std::map<std::string, std::string>::const_iterator iter;
+ iter = parsed_options.find("merge");
+ should_merge_includes_ = (iter != parsed_options.end());
+
}
virtual ~t_json_generator() {}
@@ -66,30 +73,45 @@
void generate_typedef(t_typedef* ttypedef);
void generate_enum(t_enum* tenum);
void generate_program();
- void generate_consts(vector<t_const*>);
- void generate_function(t_function* tfunc);
- void generate_field(t_field* field);
+ void generate_function(t_function * tfunc);
+ void generate_field(t_field * field);
void generate_service(t_service* tservice);
void generate_struct(t_struct* tstruct);
private:
- std::ofstream f_json_;
- std::stack<bool> _commaNeeded;
- string get_type_name(t_type* type);
- string get_const_value(t_const_value* val);
+ bool should_merge_includes_;
- void start_object();
+ std::ofstream f_json_;
+ std::stack<bool> comma_needed_;
+
+ string get_type_name(t_type* ttype);
+ string get_qualified_name(t_type* ttype);
+
+ void start_object(bool should_indent=true);
void start_array();
- void write_key(string key, string val);
- void write_key_int(string key, int val);
- void end_object(bool newLine);
- void end_array(bool newLine);
+ void end_object();
+ void end_array();
void write_comma_if_needed();
void indicate_comma_needed();
- string escapeJsonString(const string& input);
-
+ string escape_json_string(const string& input);
+ string json_str(const string& str);
void merge_includes(t_program*);
+
+ void generate_constant(t_const* con);
+
+ void write_type_spec_entry(const char* name, t_type* ttype);
+ void write_type_spec_object(const char* name, t_type* ttype);
+ void write_type_spec(t_type* ttype);
+ void write_string(const string& value);
+ void write_integer(long value);
+ void write_double(double value);
+ void write_value(t_type* tvalue);
+ void write_const_value(t_const_value* value, bool force_string=false);
+ void write_key_and(string key);
+ void write_key_and_string(string key, string val);
+ void write_key_and_integer(string key, int val);
+ void write_key_and_bool(string key, bool val);
};
void t_json_generator::init_generator() {
@@ -98,11 +120,13 @@
string f_json_name = get_out_dir() + program_->get_name() + ".json";
f_json_.open(f_json_name.c_str());
- // Merge all included programs into this one so we can output one big file.
- merge_includes(program_);
+ //Merge all included programs into this one so we can output one big file.
+ if (should_merge_includes_) {
+ merge_includes(program_);
+ }
}
-string t_json_generator::escapeJsonString(const string& input) {
+string t_json_generator::escape_json_string(const string& input) {
std::ostringstream ss;
for (std::string::const_iterator iter = input.begin(); iter != input.end(); iter++) {
switch (*iter) {
@@ -138,53 +162,108 @@
return ss.str();
}
-void t_json_generator::start_object() {
- f_json_ << "{";
- _commaNeeded.push(false);
+void t_json_generator::start_object(bool should_indent) {
+ f_json_ << (should_indent ? indent() : "") << "{" << endl;
+ indent_up();
+ comma_needed_.push(false);
}
void t_json_generator::start_array() {
- f_json_ << "[";
- _commaNeeded.push(false);
+ f_json_ << "[" << endl;
+ indent_up();
+ comma_needed_.push(false);
}
void t_json_generator::write_comma_if_needed() {
- if (_commaNeeded.top())
- f_json_ << ",";
+ if (comma_needed_.top()) {
+ f_json_ << "," << endl;
+ }
}
void t_json_generator::indicate_comma_needed() {
- _commaNeeded.pop();
- _commaNeeded.push(true);
+ comma_needed_.pop();
+ comma_needed_.push(true);
}
-void t_json_generator::write_key(string key, string val) {
+void t_json_generator::write_key_and(string key) {
write_comma_if_needed();
- f_json_ << quot << key << quot << ":" << quot << escapeJsonString(val) << quot;
+ indent(f_json_) << json_str(key) << ": ";
indicate_comma_needed();
}
-void t_json_generator::write_key_int(string key, int val) {
+void t_json_generator::write_key_and_integer(string key, int val) {
write_comma_if_needed();
- f_json_ << quot << key << quot << ":" << quot << val << quot;
+ indent(f_json_) << json_str(key) << ": " << std::to_string(val);
indicate_comma_needed();
}
-void t_json_generator::end_object(bool newLine) {
- f_json_ << "}";
- if (newLine)
- f_json_ << endl;
- _commaNeeded.pop();
+void t_json_generator::write_key_and_string(string key, string val) {
+ write_comma_if_needed();
+ indent(f_json_) << json_str(key) << ": " << json_str(val);
+ indicate_comma_needed();
}
-void t_json_generator::end_array(bool newLine) {
- f_json_ << "]";
- if (newLine)
+void t_json_generator::write_key_and_bool(string key, bool val) {
+ write_comma_if_needed();
+ indent(f_json_) << json_str(key) << ": " << (val ? "true" : "false");
+ indicate_comma_needed();
+}
+
+void t_json_generator::end_object() {
+ indent_down();
+ f_json_ << endl << indent() << "}";
+ comma_needed_.pop();
+}
+
+void t_json_generator::end_array() {
+ indent_down();
+ if (comma_needed_.top()) {
f_json_ << endl;
- _commaNeeded.pop();
+ }
+ indent(f_json_) << "]";
+ comma_needed_.pop();
+}
+
+void t_json_generator::write_type_spec_object(const char* name, t_type* ttype) {
+ ttype = ttype->get_true_type();
+ if (ttype->is_struct() || ttype->is_xception() || ttype->is_container()) {
+ write_key_and(name);
+ start_object(NO_INDENT);
+ write_key_and("typeId");
+ write_type_spec(ttype);
+ end_object();
+ }
+}
+
+void t_json_generator::write_type_spec_entry(const char* name, t_type* ttype) {
+ write_key_and(name);
+ write_type_spec(ttype);
+}
+
+void t_json_generator::write_type_spec(t_type* ttype) {
+ ttype = ttype->get_true_type();
+
+ write_string(get_type_name(ttype));
+
+ if (ttype->is_struct() || ttype->is_xception()) {
+ write_key_and_string("class", get_qualified_name(ttype));
+ } else if (ttype->is_map()) {
+ t_type* ktype = ((t_map*)ttype)->get_key_type();
+ t_type* vtype = ((t_map*)ttype)->get_val_type();
+ write_key_and_string("keyTypeId", get_type_name(ktype));
+ write_key_and_string("valueTypeId", get_type_name(vtype));
+ write_type_spec_object("keyType", ktype);
+ write_type_spec_object("valueType", vtype);
+ } else if (ttype->is_list() || ttype->is_set()) {
+ t_type* etype = ((t_list*)ttype)->get_elem_type();
+ write_key_and_string("elemTypeId", get_type_name(etype));
+ write_type_spec_object("elemType", etype);
+ }
+
}
void t_json_generator::close_generator() {
+ f_json_ << endl;
f_json_.close();
}
@@ -220,7 +299,7 @@
program->add_const(*c_iter);
}
- // Generate services
+ // merge services
vector<t_service*> services = include->get_services();
vector<t_service*>::iterator sv_iter;
for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) {
@@ -230,46 +309,71 @@
}
void t_json_generator::generate_program() {
- // Initialize the generator
- init_generator();
- start_object();
- write_key("name", program_->get_name());
- if (program_->has_doc())
- write_key("doc", program_->get_doc());
+ init_generator();
+
+ start_object();
+ write_key_and_string("name", program_->get_name());
+ if (program_->has_doc()) {
+ write_key_and_string("doc", program_->get_doc());
+ }
+
+ // When merging includes, the "namespaces" and "includes" sections
+ // become ambiguous, so just skip them.
+ if (!should_merge_includes_) {
+ // Generate namespaces
+ write_key_and("namespaces");
+ start_object(NO_INDENT);
+ const map<string,string>& namespaces = program_->get_namespaces();
+ map<string,string>::const_iterator ns_it;
+ for (ns_it = namespaces.begin(); ns_it != namespaces.end(); ++ns_it) {
+ write_key_and_string(ns_it->first, ns_it->second);
+ indicate_comma_needed();
+ }
+ end_object();
+
+ // Generate includes
+ write_key_and("includes");
+ start_array();
+ const vector<t_program*> includes = program_->get_includes();
+ vector<t_program*>::const_iterator inc_it;
+ for (inc_it = includes.begin(); inc_it != includes.end(); ++inc_it) {
+ write_comma_if_needed();
+ write_string((*inc_it)->get_name());
+ indicate_comma_needed();
+ }
+ end_array();
+ }
// Generate enums
+ write_key_and("enums");
+ start_array();
vector<t_enum*> enums = program_->get_enums();
vector<t_enum*>::iterator en_iter;
- f_json_ << ",\"enums\":";
- start_array();
- f_json_ << endl;
for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) {
write_comma_if_needed();
generate_enum(*en_iter);
indicate_comma_needed();
}
- end_array(true);
+ end_array();
// Generate typedefs
+ write_key_and("typedefs");
+ start_array();
vector<t_typedef*> typedefs = program_->get_typedefs();
vector<t_typedef*>::iterator td_iter;
- f_json_ << ",\"typedefs\":";
- start_array();
- f_json_ << endl;
for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) {
write_comma_if_needed();
generate_typedef(*td_iter);
indicate_comma_needed();
}
- end_array(true);
+ end_array();
// Generate structs, exceptions, and unions in declared order
+ write_key_and("structs");
+ start_array();
vector<t_struct*> objects = program_->get_objects();
vector<t_struct*>::iterator o_iter;
- f_json_ << ",\"structs\":";
- start_array();
- f_json_ << endl;
for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) {
write_comma_if_needed();
if ((*o_iter)->is_xception()) {
@@ -279,227 +383,333 @@
}
indicate_comma_needed();
}
- end_array(true);
+ end_array();
// Generate constants
+ write_key_and("constants");
+ start_array();
vector<t_const*> consts = program_->get_consts();
- generate_consts(consts);
+ vector<t_const*>::iterator c_iter;
+ for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
+ write_comma_if_needed();
+ generate_constant(*c_iter);
+ indicate_comma_needed();
+ }
+ end_array();
// Generate services
+ write_key_and("services");
+ start_array();
vector<t_service*> services = program_->get_services();
vector<t_service*>::iterator sv_iter;
- f_json_ << ",\"services\":";
- start_array();
- f_json_ << endl;
for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) {
write_comma_if_needed();
- service_name_ = get_service_name(*sv_iter);
generate_service(*sv_iter);
indicate_comma_needed();
}
- end_array(false);
- end_object(true);
+ end_array();
+
+ end_object();
+
// Close the generator
close_generator();
}
void t_json_generator::generate_typedef(t_typedef* ttypedef) {
start_object();
- write_key("name", ttypedef->get_name());
- write_key("type", get_type_name(ttypedef->get_true_type()));
- if (ttypedef->has_doc())
- write_key("doc", ttypedef->get_doc());
- end_object(true);
+ write_key_and_string("name", get_qualified_name(ttypedef));
+ write_key_and_string("typeId", get_type_name(ttypedef->get_true_type()));
+ write_type_spec_object("type", ttypedef->get_true_type());
+ if (ttypedef->has_doc()) {
+ write_key_and_string("doc", ttypedef->get_doc());
+ }
+ end_object();
}
-void t_json_generator::generate_consts(vector<t_const*> consts) {
- vector<t_const*>::iterator c_iter;
- f_json_ << ",\"constants\":";
- start_array();
- f_json_ << endl;
- for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
- write_comma_if_needed();
- indicate_comma_needed();
- start_object();
- t_const* con = (*c_iter);
- write_key("name", con->get_name());
- write_key("type", get_type_name(con->get_type()));
- if (con->has_doc())
- write_key("doc", con->get_doc());
- write_key("value", get_const_value(con->get_value()));
- end_object(true);
+
+void t_json_generator::write_string(const string& value) {
+ f_json_ << quot << escape_json_string(value) << quot;
+}
+
+void t_json_generator::write_integer(long value) {
+ f_json_ << std::to_string(value);
+}
+
+void t_json_generator::write_double(double value) {
+ f_json_ << std::to_string(value);
+}
+
+void t_json_generator::write_const_value(t_const_value* value, bool should_force_string) {
+
+ switch (value->get_type()) {
+
+ case t_const_value::CV_IDENTIFIER:
+ case t_const_value::CV_INTEGER:
+ if (should_force_string) {
+ write_string(std::to_string(value->get_integer()));
+ } else {
+ write_integer(value->get_integer());
+ }
+ break;
+
+ case t_const_value::CV_DOUBLE:
+ if (should_force_string) {
+ write_string(std::to_string(value->get_double()));
+ } else {
+ write_double(value->get_double());
+ }
+ break;
+
+ case t_const_value::CV_STRING:
+ write_string(value->get_string());
+ break;
+
+ case t_const_value::CV_LIST: {
+ start_array();
+ std::vector<t_const_value*> list = value->get_list();
+ std::vector<t_const_value*>::iterator lit;
+ for (lit = list.begin(); lit != list.end(); ++lit) {
+ write_comma_if_needed();
+ write_const_value(*lit);
+ indicate_comma_needed();
+ }
+ end_array();
+ break;
+ }
+
+ case t_const_value::CV_MAP: {
+ start_object(NO_INDENT);
+ std::map<t_const_value*, t_const_value*> map = value->get_map();
+ std::map<t_const_value*, t_const_value*>::iterator mit;
+ for (mit = map.begin(); mit != map.end(); ++mit) {
+ write_comma_if_needed();
+ // JSON objects only allow string keys
+ write_const_value(mit->first, FORCE_STRING);
+ f_json_ << ": ";
+ write_const_value(mit->second);
+ indicate_comma_needed();
+ }
+ end_object();
+ break;
+ }
+
+ default:
+ f_json_ << "null";
+ break;
}
- end_array(true);
+}
+
+string t_json_generator::json_str(const string& str) {
+ return quot + escape_json_string(str) + quot;
+}
+
+void t_json_generator::generate_constant(t_const* con) {
+ start_object();
+
+ write_key_and_string("name", con->get_name());
+ write_key_and_string("typeId", get_type_name(con->get_type()));
+ write_type_spec_object("type", con->get_type());
+
+ if (con->has_doc()) {
+ write_key_and_string("doc", con->get_doc());
+ }
+
+ write_key_and("value");
+ write_const_value(con->get_value());
+
+ end_object();
}
void t_json_generator::generate_enum(t_enum* tenum) {
start_object();
- write_key("name", tenum->get_name());
- if (tenum->has_doc())
- write_key("doc", tenum->get_doc());
- f_json_ << ",\"members\":";
+
+ write_key_and_string("name", tenum->get_name());
+
+ if (tenum->has_doc()) {
+ write_key_and_string("doc", tenum->get_doc());
+ }
+
+ write_key_and("members");
start_array();
vector<t_enum_value*> values = tenum->get_constants();
vector<t_enum_value*>::iterator val_iter;
for (val_iter = values.begin(); val_iter != values.end(); ++val_iter) {
- t_enum_value* val = (*val_iter);
write_comma_if_needed();
+ t_enum_value* val = (*val_iter);
start_object();
- write_key("name", val->get_name());
- write_key_int("value", val->get_value());
- if (val->has_doc())
- write_key("doc", val->get_doc());
- end_object(false);
+ write_key_and_string("name", val->get_name());
+ write_key_and_integer("value", val->get_value());
+ if (val->has_doc()) {
+ write_key_and_string("doc", val->get_doc());
+ }
+ end_object();
indicate_comma_needed();
}
- end_array(false);
- end_object(true);
+ end_array();
+
+ end_object();
}
void t_json_generator::generate_struct(t_struct* tstruct) {
start_object();
- write_key("name", tstruct->get_name());
- if (tstruct->has_doc())
- write_key("doc", tstruct->get_doc());
- if (tstruct->is_xception())
- write_key("isException", "true");
- vector<t_field*> members = tstruct->get_members();
- vector<t_field*>::iterator mem_iter = members.begin();
- f_json_ << ",\"fields\":";
- start_array();
- for (; mem_iter != members.end(); mem_iter++) {
- generate_field((*mem_iter));
+
+ write_key_and_string("name", tstruct->get_name());
+
+ if (tstruct->has_doc()) {
+ write_key_and_string("doc", tstruct->get_doc());
}
- end_array(false);
- end_object(true);
+
+ write_key_and_bool("isException", tstruct->is_xception());
+
+ write_key_and_bool("isUnion", tstruct->is_union());
+
+ write_key_and("fields");
+ start_array();
+ vector<t_field*> members = tstruct->get_members();
+ vector<t_field*>::iterator mem_iter;
+ for (mem_iter = members.begin(); mem_iter != members.end(); mem_iter++) {
+ write_comma_if_needed();
+ generate_field(*mem_iter);
+ indicate_comma_needed();
+ }
+ end_array();
+
+ end_object();
}
void t_json_generator::generate_service(t_service* tservice) {
start_object();
- write_key("name", tservice->get_name());
- if (tservice->get_extends())
- write_key("extendsType", tservice->get_extends()->get_name());
- if (tservice->has_doc())
- write_key("doc", tservice->get_doc());
+
+ write_key_and_string("name", get_qualified_name(tservice));
+
+ if (tservice->get_extends()) {
+ write_key_and_string("extends", get_qualified_name(tservice->get_extends()));
+ }
+
+ if (tservice->has_doc()) {
+ write_key_and_string("doc", tservice->get_doc());
+ }
+
+ write_key_and("functions");
+ start_array();
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::iterator fn_iter = functions.begin();
- f_json_ << ",\"functions\":";
- start_array();
for (; fn_iter != functions.end(); fn_iter++) {
- t_function* func = (*fn_iter);
write_comma_if_needed();
+ generate_function(*fn_iter);
indicate_comma_needed();
- generate_function(func);
}
- end_array(false);
- end_object(true);
+ end_array();
+
+ end_object();
}
void t_json_generator::generate_function(t_function* tfunc) {
start_object();
- write_key("name", tfunc->get_name());
- write_key("returnType", get_type_name(tfunc->get_returntype()));
- if (tfunc->is_oneway())
- write_key("oneWay", "true");
- if (tfunc->has_doc())
- write_key("doc", tfunc->get_doc());
+
+ write_key_and_string("name", tfunc->get_name());
+
+ write_key_and_string("returnTypeId", get_type_name(tfunc->get_returntype()));
+ write_type_spec_object("returnType", tfunc->get_returntype());
+
+ write_key_and_bool("oneway", tfunc->is_oneway());
+
+ if (tfunc->has_doc()) {
+ write_key_and_string("doc", tfunc->get_doc());
+ }
+
+ write_key_and("arguments");
+ start_array();
vector<t_field*> members = tfunc->get_arglist()->get_members();
vector<t_field*>::iterator mem_iter = members.begin();
- f_json_ << ",\"arguments\":";
- start_array();
for (; mem_iter != members.end(); mem_iter++) {
- generate_field((*mem_iter));
+ write_comma_if_needed();
+ generate_field(*mem_iter);
+ indicate_comma_needed();
}
- end_array(false);
+ end_array();
+ write_key_and("exceptions");
+ start_array();
vector<t_field*> excepts = tfunc->get_xceptions()->get_members();
vector<t_field*>::iterator ex_iter = excepts.begin();
- f_json_ << ",\"exceptions\":";
- start_array();
for (; ex_iter != excepts.end(); ex_iter++) {
- generate_field((*ex_iter));
+ write_comma_if_needed();
+ generate_field(*ex_iter);
+ indicate_comma_needed();
}
- end_array(false);
- end_object(false);
+ end_array();
+
+ end_object();
}
-void t_json_generator::generate_field(t_field* field) {
- write_comma_if_needed();
+void t_json_generator::generate_field(t_field * field) {
start_object();
- write_key_int("index", field->get_key());
- write_key("name", field->get_name());
- write_key("type", get_type_name(field->get_type()));
- if (field->has_doc())
- write_key("doc", field->get_doc());
+
+ write_key_and_integer("key", field->get_key());
+ write_key_and_string("name", field->get_name());
+ write_key_and_string("typeId", get_type_name(field->get_type()));
+ write_type_spec_object("type", field->get_type());
+
+ if (field->has_doc()) {
+ write_key_and_string("doc", field->get_doc());
+ }
+
+ write_key_and("required");
switch (field->get_req()) {
- case t_field::T_REQUIRED:
- write_key("required", "true");
- break;
- default:
- write_key("required", "false");
- break;
+ case t_field::T_REQUIRED:
+ write_string("required");
+ break;
+ case t_field::T_OPT_IN_REQ_OUT:
+ write_string("req_out");
+ break;
+ default:
+ write_string("optional");
+ break;
}
- if (field->get_value())
- write_key("default", get_const_value(field->get_value()));
- end_object(false);
- indicate_comma_needed();
-}
-string t_json_generator::get_const_value(t_const_value* tvalue) {
+ if (field->get_value()) {
+ write_key_and("default");
+ write_const_value(field->get_value());
+ }
- switch (tvalue->get_type()) {
- case t_const_value::CV_INTEGER:
- return tvalue->get_string();
- case t_const_value::CV_DOUBLE:
- return tvalue->get_string();
- case t_const_value::CV_STRING:
- return tvalue->get_string();
- case t_const_value::CV_LIST: {
- string list = "[";
- vector<t_const_value*> list_elems = tvalue->get_list();
- ;
- vector<t_const_value*>::iterator list_iter;
- bool first = true;
- for (list_iter = list_elems.begin(); list_iter != list_elems.end(); list_iter++) {
- if (!first)
- list += ",";
- first = false;
- list += get_const_value(*list_iter);
- }
- return list + "]";
- }
- case t_const_value::CV_IDENTIFIER:
- return tvalue->get_identifier_name();
- case t_const_value::CV_MAP:
- map<t_const_value*, t_const_value*> map_elems = tvalue->get_map();
- map<t_const_value*, t_const_value*>::iterator map_iter;
- string map = "[";
- bool first = true;
- for (map_iter = map_elems.begin(); map_iter != map_elems.end(); map_iter++) {
- if (!first)
- map += ",";
- first = false;
- map += get_const_value(map_iter->first) + ":";
- map += get_const_value(map_iter->second);
- }
- return map + "]";
- }
- return "UNKNOWN";
+ end_object();
}
+
string t_json_generator::get_type_name(t_type* ttype) {
- if (ttype->is_container()) {
- if (ttype->is_list()) {
- return "list<" + get_type_name(((t_list*)ttype)->get_elem_type()) + ">";
- } else if (ttype->is_set()) {
- return "set<" + get_type_name(((t_set*)ttype)->get_elem_type()) + ">";
- } else if (ttype->is_map()) {
- return "map<" + get_type_name(((t_map*)ttype)->get_key_type()) + +","
- + get_type_name(((t_map*)ttype)->get_val_type()) + ">";
- }
- } else if (ttype->is_base_type()) {
- return (((t_base_type*)ttype)->is_binary() ? "binary" : ttype->get_name());
+ ttype = ttype->get_true_type();
+ if (ttype->is_list()) {
+ return "list";
}
- return ttype->get_name();
+ if (ttype->is_set()) {
+ return "set";
+ }
+ if (ttype->is_map()) {
+ return "map";
+ }
+ if (ttype->is_enum()) {
+ return "i32";
+ }
+ if (ttype->is_struct()) {
+ return ((t_struct*)ttype)->is_union() ? "union" : "struct";
+ }
+ if (ttype->is_xception()) {
+ return "exception";
+ }
+ if (ttype->is_base_type() && ((t_base_type*)ttype)->is_binary()) {
+ return "binary";
+ }
+ return ttype->get_fingerprint_material();
}
-THRIFT_REGISTER_GENERATOR(json, "JSON", "")
+string t_json_generator::get_qualified_name(t_type* ttype) {
+ if (should_merge_includes_ || ttype->get_program() == program_) {
+ return ttype->get_name();
+ }
+ return ttype->get_program()->get_name() + "." + ttype->get_name();
+}
+
+
+THRIFT_REGISTER_GENERATOR(json, "JSON",
+" merge: Generate output with included files merged\n"
+)
diff --git a/compiler/cpp/src/parse/t_program.h b/compiler/cpp/src/parse/t_program.h
index 386f589..0c3de38 100644
--- a/compiler/cpp/src/parse/t_program.h
+++ b/compiler/cpp/src/parse/t_program.h
@@ -93,13 +93,14 @@
const std::string& get_include_prefix() const { return include_prefix_; }
// Accessors for program elements
- const std::vector<t_typedef*>& get_typedefs() const { return typedefs_; }
- const std::vector<t_enum*>& get_enums() const { return enums_; }
- const std::vector<t_const*>& get_consts() const { return consts_; }
- const std::vector<t_struct*>& get_structs() const { return structs_; }
- const std::vector<t_struct*>& get_xceptions() const { return xceptions_; }
- const std::vector<t_struct*>& get_objects() const { return objects_; }
- const std::vector<t_service*>& get_services() const { return services_; }
+ const std::vector<t_typedef*>& get_typedefs() const { return typedefs_; }
+ const std::vector<t_enum*>& get_enums() const { return enums_; }
+ const std::vector<t_const*>& get_consts() const { return consts_; }
+ const std::vector<t_struct*>& get_structs() const { return structs_; }
+ const std::vector<t_struct*>& get_xceptions() const { return xceptions_; }
+ const std::vector<t_struct*>& get_objects() const { return objects_; }
+ const std::vector<t_service*>& get_services() const { return services_; }
+ const std::map<std::string,std::string>& get_namespaces() const { return namespaces_; }
// Program elements
void add_typedef(t_typedef* td) { typedefs_.push_back(td); }