28 #include <boost/algorithm/string.hpp>
35 #include <boost/foreach.hpp>
36 #include <boost/tokenizer.hpp>
48 const map<string, string>& parsed_options,
49 const string& option_string)
52 (void) parsed_options;
54 out_dir_base_ =
"gen-doc";
56 escape_[
'&'] =
"&";
57 escape_[
'<'] =
"<";
58 escape_[
'>'] =
">";
59 escape_[
'"'] =
""";
60 escape_[
'\''] =
"'";
99 string get_object_type(
t_sandesh* tsandesh);
100 string get_doc_member(
t_sandesh* tsandesh,
string member);
104 void generate_index();
105 void generate_stats_schema_program();
107 void generate_const_enum_typedef_object_program();
108 void generate_doc_type(ofstream &f_out);
109 void generate_program();
110 void generate_program_toc(ofstream &f_out,
string fsuffix,
112 void generate_program_toc_row(
t_program* tprog, ofstream &f_out,
114 bool generate_sandesh_program_doc(
t_program* tprog, ofstream &f_out,
116 void generate_sandesh_program_doc_schema(
t_program* tprog, ofstream &f_out,
118 void generate_sandesh_program_doc_schema_uve(
t_program* tprog, ofstream &f_out,
125 template <
typename T>
126 void generate_stat_table_schema(
string,
t_field*, T*,
string, vector<string>&);
127 template <
typename T>
128 void generate_stat_schema_map(
string,
t_type*,
t_type*,
t_field*, T*,
bool,
bool, vector<string>&);
129 template <
typename T>
130 void generate_stat_schema_list(
string,
t_type*,
t_field*, T*,
bool,
bool, vector<string>&);
131 t_struct* find_struct_with_name(
string sname);
132 template <
typename T>
133 void generate_stat_schema_struct(
string,
t_field*,
t_struct*, T*,
bool, vector<string>&);
134 template <
typename T>
135 void extract_tags(T*, map<
string, vector<string> >&, vector<string>&, vector<string>&);
136 string generate_stat_schema_struct_base_member(
string,
t_field*,
string,
t_field*);
137 void generate_stat_table_schema_header(
string,
string,
string,
string);
138 string get_datatype_from_tfield(
t_type* tfield);
139 string generate_table_entry(
string name,
string datatype,
string index,
string);
140 template <
typename T>
142 string get_uve_type(
string,
t_field*);
143 template <
typename T>
145 void generate_stat_schema_struct_members(
string name,
t_field*,
t_struct*, vector<string>, map<
string, vector<string> >, vector<string>&);
146 void is_indexed_or_suffixed_field(
string, vector<string>, map<
string, vector<string> >,
string&,
bool&,
bool&);
147 template <
typename T>
148 void generate_stat_schema_suffixes(
string,
t_field*,
t_struct*, T*, map<
string, vector<string> >&, vector<string>&);
149 template <
typename T>
150 void generate_stat_schema_toplevel_tags(T*, vector<string>&, vector<string>&,
t_field*);
151 void generate_stat_tables_schema(
t_sandesh*);
152 template <
typename T>
153 void generate_stat_tables_schema(T*,
const vector<t_field*>,
string,
string, vector<string>&);
154 string get_display_name_from_comments(
t_field*);
155 template <
typename T>
156 void find_recursive_tags(T*,
t_field*,
string,
string, vector<string>&);
157 template <
typename T>
158 void find_recursive_tags_struct(T*,
t_field*,
string,
string,
string, vector<string>&);
159 template <
typename T>
160 void find_recursive_tags_list(T*,
t_field*,
string,
t_type*,
string, vector<string>&);
161 template <
typename T>
162 void find_recursive_tags_map(T*,
t_field*,
string,
t_type*,
t_type*,
string, vector<string>&);
163 string find_obj_table_name(
const vector<t_field*>);
170 bool generate_introspect_cli (
t_sandesh* , ofstream &f_out,
bool &first_file);
172 void print_doc (
t_doc* tdoc, ofstream &f_out);
173 int print_type (
t_type* ttype, ofstream &f_out);
174 void print_const_value(
t_const_value* tvalue, ofstream &f_out);
175 void print_sandesh (
t_sandesh* tdoc, ofstream &f_out);
176 void print_sandesh_message(
t_sandesh* tdoc, ofstream &f_out);
177 void print_sandesh_message_table(
t_sandesh* tdoc, ofstream &f_out);
178 void print_doc_string (
string doc, ofstream &f_out);
198 void generate_typedef (
t_typedef* ttypedef, ofstream &f_out);
199 void generate_enum (
t_enum* tenum, ofstream &f_out);
200 void generate_const (
t_const* tconst, ofstream &f_out);
201 void generate_consts (vector<t_const*> consts, ofstream &f_out);
202 void generate_struct (
t_struct* tstruct, ofstream &f_out);
203 void generate_struct_table (
t_struct* tstruct, ofstream &f_out);
204 void generate_sandesh (
t_sandesh* tsandesh, ofstream &f_out);
205 void generate_sandesh_uve (
t_sandesh* tsandesh, ofstream &f_out);
215 case doc_ftype::LOGS:
216 if (tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) {
220 case doc_ftype::LOGS_LEVEL_INVALID:
221 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
226 case doc_ftype::LOGS_LEVEL_DEBUG:
227 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
228 get_sandesh_level(tsandesh) == sandesh_level::DBG) {
232 case doc_ftype::LOGS_LEVEL_INFO:
233 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
234 get_sandesh_level(tsandesh) == sandesh_level::INFO) {
238 case doc_ftype::LOGS_LEVEL_NOTICE:
239 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
240 get_sandesh_level(tsandesh) == sandesh_level::NOTICE) {
244 case doc_ftype::LOGS_LEVEL_WARN:
245 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
246 get_sandesh_level(tsandesh) == sandesh_level::WARN) {
250 case doc_ftype::LOGS_LEVEL_ERR:
251 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
252 get_sandesh_level(tsandesh) == sandesh_level::ERR) {
256 case doc_ftype::LOGS_LEVEL_CRIT:
257 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
258 get_sandesh_level(tsandesh) == sandesh_level::CRIT) {
262 case doc_ftype::LOGS_LEVEL_ALERT:
263 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
264 get_sandesh_level(tsandesh) == sandesh_level::ALERT) {
268 case doc_ftype::LOGS_LEVEL_EMERG:
269 if ((tbtype->is_sandesh_system() || tbtype->is_sandesh_object()) &&
270 get_sandesh_level(tsandesh) == sandesh_level::EMERG) {
274 case doc_ftype::UVES:
275 if (tbtype->is_sandesh_uve()) {
279 case doc_ftype::TRACES:
280 if (tbtype->is_sandesh_trace() || tbtype->is_sandesh_trace_object()) {
284 case doc_ftype::INTROSPECT:
285 if (tbtype->is_sandesh_request() || tbtype->is_sandesh_response()) {
297 case doc_ftype::LOGS:
299 case doc_ftype::LOGS_LEVEL_INVALID:
300 return "_logs.invalid";
301 case doc_ftype::LOGS_LEVEL_DEBUG:
302 return "_logs.debug";
303 case doc_ftype::LOGS_LEVEL_INFO:
305 case doc_ftype::LOGS_LEVEL_NOTICE:
306 return "_logs.notice";
307 case doc_ftype::LOGS_LEVEL_WARN:
309 case doc_ftype::LOGS_LEVEL_ERR:
310 return "_logs.error";
311 case doc_ftype::LOGS_LEVEL_CRIT:
313 case doc_ftype::LOGS_LEVEL_ALERT:
314 return "_logs.alert";
315 case doc_ftype::LOGS_LEVEL_EMERG:
316 return "_logs.emerg";
317 case doc_ftype::UVES:
319 case doc_ftype::TRACES:
321 case doc_ftype::INTROSPECT:
322 return "_introspect";
330 case doc_ftype::LOGS:
331 return "all systemlog and objectlog";
332 case doc_ftype::LOGS_LEVEL_INVALID:
333 return "systemlog and objectlog with unknown severity";
334 case doc_ftype::LOGS_LEVEL_DEBUG:
335 return "debug systemlog and objectlog";
336 case doc_ftype::LOGS_LEVEL_INFO:
337 return "informational systemlog and objectlog";
338 case doc_ftype::LOGS_LEVEL_NOTICE:
339 return "notice systemlog and objectlog";
340 case doc_ftype::LOGS_LEVEL_WARN:
341 return "warning systemlog and objectlog";
342 case doc_ftype::LOGS_LEVEL_ERR:
343 return "error systemlog and objectlog";
344 case doc_ftype::LOGS_LEVEL_CRIT:
345 return "critical systemlog and objectlog";
346 case doc_ftype::LOGS_LEVEL_ALERT:
347 return "alert systemlog and objectlog";
348 case doc_ftype::LOGS_LEVEL_EMERG:
349 return "emergency systemlog and objectlog";
350 case doc_ftype::UVES:
352 case doc_ftype::TRACES:
354 case doc_ftype::INTROSPECT:
366 f_out <<
"<table><tr><th>Module</th><th>Messages</th></tr>" << endl;
367 generate_program_toc_row(program_, f_out, fsuffix, dtype);
368 f_out <<
"</table>" << endl;
376 string fname = tprog->
get_name() + fsuffix +
".html";
377 f_out <<
"<tr>" << endl <<
"<td>" << tprog->
get_name() <<
"</td><td>";
378 if (!tprog->get_sandeshs().empty()) {
379 vector<t_sandesh*> sandeshs = tprog->get_sandeshs();
380 vector<t_sandesh*>::iterator snh_iter;
381 for (snh_iter = sandeshs.begin(); snh_iter != sandeshs.end(); ++snh_iter) {
382 string name = get_sandesh_name(*snh_iter);
383 if (is_sandesh_type(*snh_iter, dtype)) {
384 if (dtype == doc_ftype::UVES) {
385 vector<t_field*> members = (*snh_iter)->get_members();
386 BOOST_FOREACH(
t_field *tfield, members) {
388 f_out <<
"<a href=\"" << fname <<
"#Snh_" << name <<
"\">" << name
389 <<
"</a><br/>" << endl;
392 f_out <<
"<a href=\"" << fname <<
"#Snh_" << name <<
"\">" << name
393 <<
"</a><br/>" << endl;
398 f_out <<
"</td>" << endl;
403 f_out <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" << endl;
404 f_out <<
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" << endl;
405 f_out <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" << endl;
406 f_out <<
"<head>" << endl;
407 f_out <<
"<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />" << endl;
408 f_out <<
"<link href=\"/doc-style.css\" rel=\"stylesheet\" type=\"text/css\"/>"
413 string fname = get_out_dir() + program_->get_name() +
"_stats_tables.json";
414 f_stats_tables_.open(fname.c_str());
415 stat_table_created_ =
false;
416 first_member_ =
true;
417 f_stats_tables_ <<
"{\"_STAT_TABLES\":[" << endl;
418 if (!program_->get_sandeshs().empty()) {
420 vector<t_sandesh*> sandeshs = program_->get_sandeshs();
421 vector<t_sandesh*>::iterator snh_iter;
422 for (snh_iter = sandeshs.begin(); snh_iter != sandeshs.end(); ++snh_iter) {
423 generate_stat_tables_schema(*snh_iter);
426 f_stats_tables_ <<
"]" << endl <<
"}" << endl;
431 if (dtype == doc_ftype::UVES)
432 return generate_sandesh_program_doc_schema_uve(tprog, f_out, fsuffix);
434 f_out <<
"{\"messages\":{" << endl;
435 if (!tprog->get_sandeshs().empty()) {
436 vector<t_sandesh*> sandeshs = tprog->get_sandeshs();
437 vector<t_sandesh*>::iterator snh_iter;
438 for (snh_iter = sandeshs.begin(); snh_iter != sandeshs.end(); ++snh_iter) {
439 if (!is_sandesh_type(*snh_iter, dtype)) {
445 f_out <<
"," << endl;
447 string sandesh_name(get_sandesh_name(*snh_iter));
448 string fname(tprog->
get_name() + fsuffix +
".html");
449 f_out <<
"\"" << sandesh_name <<
"\":{\"fingerprint\":\"" <<
450 (*snh_iter)->get_ascii_fingerprint() <<
"\", \"href\":\"" <<
451 fname <<
"#Snh_" << sandesh_name <<
"\"";
452 if (dtype == doc_ftype::LOGS) {
453 f_out <<
", \"severity\":\"" <<
454 sandesh_level_to_string(get_sandesh_level(*snh_iter)) <<
"\"";
455 }
else if (dtype == doc_ftype::UVES) {
456 f_out <<
", \"object\":\"" << get_object_type(*snh_iter) <<
"\"";
460 f_out <<
"}," << endl <<
"\"sandesh_cli\":{" << endl;
461 bool first_file =
true;
462 for (snh_iter = sandeshs.begin(); snh_iter != sandeshs.end(); ++snh_iter) {
463 sandesh_name_ = get_sandesh_name(*snh_iter);
464 if (!is_sandesh_type(*snh_iter, doc_ftype::INTROSPECT)) {
467 generate_introspect_cli(*snh_iter, f_out, first_file);
469 f_out << endl <<
"}" << endl <<
"}" << endl;
471 f_out <<
"}" << endl <<
"}" << endl;
476 ofstream &f_out,
string fsuffix) {
478 f_out <<
"{\"messages\":{" << endl;
479 if (!tprog->get_sandeshs().empty()) {
480 vector<t_sandesh*> sandeshs = tprog->get_sandeshs();
481 vector<t_sandesh*>::iterator snh_iter;
482 for (snh_iter = sandeshs.begin(); snh_iter != sandeshs.end(); ++snh_iter) {
483 if (!is_sandesh_type(*snh_iter, doc_ftype::UVES)) {
489 f_out <<
"," << endl;
491 string sandesh_name(get_sandesh_name(*snh_iter));
492 vector<t_field*> smembers = (*snh_iter)->get_members();
493 if (smembers.size() == 1 && smembers[0]->get_type()->is_struct()) {
494 sandesh_name = smembers[0]->get_type()->get_name();
496 string fname(tprog->
get_name() + fsuffix +
".html");
497 f_out <<
"\"" << sandesh_name <<
"\":{\"fingerprint\":\"" <<
498 (*snh_iter)->get_ascii_fingerprint() <<
"\", \"href\":\"" <<
499 fname <<
"#Snh_" << sandesh_name <<
"\"";
500 if (get_object_type(*snh_iter) !=
"") {
501 f_out <<
", \"object\":\"" << get_object_type(*snh_iter) <<
"\"";
505 f_out <<
"}," << endl <<
"\"sandesh_cli\":{" << endl;
506 bool first_file =
true;
507 for (snh_iter = sandeshs.begin(); snh_iter != sandeshs.end(); ++snh_iter) {
508 sandesh_name_ = get_sandesh_name(*snh_iter);
509 if (!is_sandesh_type(*snh_iter, doc_ftype::UVES)) {
512 generate_introspect_cli(*snh_iter, f_out, first_file);
514 f_out << endl <<
"}" << endl <<
"}" << endl;
516 f_out <<
"}" << endl <<
"}" << endl;
523 generate_doc_type(f_out);
525 string mdesc(get_doc_file_description(dtype));
526 f_out <<
"<title>Documentation for " << mdesc <<
" messages in " <<
527 "module: " << tprog->
get_name() <<
"</title></head><body>" << endl <<
528 "<h1>Documentation for " << mdesc <<
" messages in module: "
529 << tprog->
get_name() <<
"</h1>" << endl;
531 print_doc(tprog, f_out);
533 generate_program_toc(f_out, fsuffix, dtype);
536 if (!tprog->get_sandeshs().empty()) {
537 f_out <<
"<hr/><h2 id=\"Messages\">Messages</h2>" << endl;
538 vector<t_sandesh*> sandeshs = tprog->get_sandeshs();
539 vector<t_sandesh*>::iterator snh_iter;
540 for (snh_iter = sandeshs.begin(); snh_iter != sandeshs.end(); ++snh_iter) {
541 if (!is_sandesh_type(*snh_iter, dtype)) {
545 sandesh_name_ = get_sandesh_name(*snh_iter);
546 f_out <<
"<div class=\"definition\">";
547 if (dtype == doc_ftype::UVES) {
548 generate_sandesh_uve(*snh_iter, f_out);
550 generate_sandesh(*snh_iter, f_out);
555 f_out <<
"</body></html>" << endl;
560 string fsuffix = get_doc_file_suffix(dtype);
562 string fname = get_out_dir() + program_->get_name() + fsuffix +
".html";
564 f_out.open(fname.c_str());
565 bool init(generate_sandesh_program_doc(program_, f_out, fsuffix, dtype));
568 string fname_schema = get_out_dir() + program_->get_name() + fsuffix +
".doc.schema.json";
569 ofstream f_out_schema;
570 f_out_schema.open(fname_schema.c_str());
571 generate_sandesh_program_doc_schema(program_, f_out_schema, fsuffix, dtype);
572 f_out_schema.close();
578 string fname = get_out_dir() + program_->get_name() + fsuffix +
".html";
579 f_out_.open(fname.c_str());
581 generate_doc_type(f_out_);
582 f_out_ <<
"<title>Documentation for constants, enums, types, and data structures in " <<
583 "module: " << program_->get_name() <<
"</title></head><body>" << endl <<
584 "<h1>Documentation for constants, enums, types, and data structures in module: "
585 << program_->get_name() <<
"</h1>" << endl;
587 print_doc(program_, f_out_);
589 if (!program_->get_consts().empty()) {
590 f_out_ <<
"<hr/><h2 id=\"Constants\">Constants</h2>" << endl;
591 vector<t_const*> consts = program_->get_consts();
593 f_out_ <<
"<tr><th>Constant</th><th>Type</th><th>Value</th></tr>" << endl;
594 generate_consts(consts, f_out_);
595 f_out_ <<
"</table>";
598 if (!program_->get_enums().empty()) {
599 f_out_ <<
"<hr/><h2 id=\"Enumerations\">Enumerations</h2>" << endl;
601 vector<t_enum*> enums = program_->get_enums();
602 vector<t_enum*>::iterator en_iter;
603 for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) {
604 generate_enum(*en_iter, f_out_);
608 if (!program_->get_typedefs().empty()) {
609 f_out_ <<
"<hr/><h2 id=\"Typedefs\">Type declarations</h2>" << endl;
611 vector<t_typedef*> typedefs = program_->get_typedefs();
612 vector<t_typedef*>::iterator td_iter;
613 for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) {
614 generate_typedef(*td_iter, f_out_);
618 if (!program_->get_objects().empty()) {
619 f_out_ <<
"<hr/><h2 id=\"Structs\">Data structures</h2>" << endl;
621 vector<t_struct*> objects = program_->get_objects();
622 vector<t_struct*>::iterator o_iter;
623 for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) {
624 generate_struct(*o_iter, f_out_);
628 f_out_ <<
"</body></html>" << endl;
636 string index_fname = get_out_dir() + program_->get_name() +
"_index.html";
637 f_index_out_.open(index_fname.c_str());
638 f_index_out_ <<
"<html>" << endl;
639 f_index_out_ <<
"<head>Documentation for " << program_->get_name() <<
"</head>" << endl;
640 f_index_out_ <<
"<link href=\"/doc-style.css\" rel=\"stylesheet\" type=\"text/css\"/>"
642 f_index_out_ <<
"<table><tr><th>Message Types</th></tr>" << endl;
643 if (f_log_initialized_) {
644 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
645 get_doc_file_suffix(doc_ftype::LOGS) <<
".html>All Logs</a></td></tr>" << endl;
647 if (f_log_emerg_initialized_) {
648 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
649 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_EMERG) <<
".html>Emergency Logs</a></td></tr>" << endl;
651 if (f_log_alert_initialized_) {
652 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
653 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_ALERT) <<
".html>Alert Logs</a></td></tr>" << endl;
655 if (f_log_crit_initialized_) {
656 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
657 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_CRIT) <<
".html>Critical Logs</a></td></tr>" << endl;
659 if (f_log_error_initialized_) {
660 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
661 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_ERR) <<
".html>Error Logs</a></td></tr>" << endl;
663 if (f_log_warn_initialized_) {
664 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
665 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_WARN) <<
".html>Warning Logs</a></td></tr>" << endl;
667 if (f_log_notice_initialized_) {
668 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
669 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_NOTICE) <<
".html>Notice Logs</a></td></tr>" << endl;
671 if (f_log_info_initialized_) {
672 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
673 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_INFO) <<
".html>Informational Logs</a></td></tr>" << endl;
675 if (f_log_debug_initialized_) {
676 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
677 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_DEBUG) <<
".html>Debugging Logs</a></td></tr>" << endl;
679 if (f_log_invalid_initialized_) {
680 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
681 get_doc_file_suffix(doc_ftype::LOGS_LEVEL_INVALID) <<
".html>Unknown severity logs</a></td></tr>" << endl;
683 if (f_uve_initialized_) {
684 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
"_uves.html>UVEs</a></td></tr>" << endl;
686 if (f_trace_initialized_) {
687 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
"_traces.html>Traces</a></td></tr>" << endl;
689 if (f_introspect_initialized_) {
690 f_index_out_ <<
"<tr><td><a href=" << program_->get_name() <<
"_introspect.html>Request-Response</a></td></tr>" << endl;
692 f_index_out_ <<
"</table>" << endl;
693 f_index_out_ <<
"</html>" << endl;
694 f_index_out_.close();
703 MKDIR(get_out_dir().c_str());
704 generate_stats_schema_program();
705 f_log_initialized_ = generate_sandesh_program(doc_ftype::LOGS);
706 f_log_invalid_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_INVALID);
707 f_log_debug_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_DEBUG);
708 f_log_info_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_INFO);
709 f_log_notice_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_NOTICE);
710 f_log_warn_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_WARN);
711 f_log_error_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_ERR);
712 f_log_crit_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_CRIT);
713 f_log_alert_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_ALERT);
714 f_log_emerg_initialized_ = generate_sandesh_program(doc_ftype::LOGS_LEVEL_EMERG);
715 f_uve_initialized_ = generate_sandesh_program(doc_ftype::UVES);
716 f_trace_initialized_ = generate_sandesh_program(doc_ftype::TRACES);
717 f_introspect_initialized_ = generate_sandesh_program(doc_ftype::INTROSPECT);
719 generate_const_enum_typedef_object_program();
724 while ((index = doc.find_first_of(
"\r\n")) != string::npos) {
726 f_out <<
"<p/>" << endl;
728 f_out << doc.substr(0, index) << endl;
730 if (index + 1 < doc.size() && doc.at(index) != doc.at(index + 1) &&
731 (doc.at(index + 1) ==
'\r' || doc.at(index + 1) ==
'\n')) {
734 doc = doc.substr(index + 1);
736 f_out << doc <<
"<br/>";
746 print_doc_string(doc, f_out);
753 vector<t_field*> members = tsandesh->
get_members();
754 BOOST_FOREACH(
t_field *tfield, members) {
755 if (tfield->get_auto_generated()) {
759 f_out <<
"<tr><th>Message</th><td>";
762 if (type->is_static_const_string()) {
767 f_out << get_escaped_string(default_val);
773 f_out << tfield->
get_name() <<
"</code>";
778 f_out <<
"</td></tr>" << endl;
784 print_sandesh_message(tsandesh, f_out);
785 f_out <<
"</table><br/>" << endl;
789 const string &ilevel) {
790 string level(ilevel);
792 boost::algorithm::trim(level);
796 boost::algorithm::to_lower(level);
797 if (level ==
"debug") {
800 if (level ==
"informational" || level ==
"info") {
803 if (level ==
"notice") {
806 if (level ==
"warning" || level ==
"warn") {
809 if (level ==
"error" || level ==
"err") {
812 if (level ==
"critical" || level ==
"crit") {
815 if (level ==
"alert") {
818 if (level ==
"emergency" || level ==
"emerg") {
840 return "informational";
849 typedef boost::tokenizer<boost::char_separator<char> >
tokenizer;
852 string doc = tsandesh->
get_doc();
854 if ((index = doc.find_first_of(
"@")) != string::npos) {
856 string fdoc(doc.substr(index + 1));
858 boost::char_separator<char> fsep(
"@");
860 BOOST_FOREACH(
const string &f, ftokens) {
864 if ((lindex = f.find_first_of(
": \t")) != string::npos) {
865 string type(f.substr(0, lindex));
866 if (lindex + 1 < f.size() && f.at(lindex) != f.at(lindex + 1) &&
867 (f.at(lindex + 1) ==
':' || f.at(lindex + 1) ==
'\t' ||
868 f.at(lindex + 1) ==
' ')) {
871 string content(f.substr(lindex + 1));
872 if (
type == member) {
883 string content = get_doc_member(tsandesh,
"object");
885 boost::algorithm::trim(content);
893 string content = get_doc_member(tsandesh,
"severity");
895 return string_to_sandesh_level(content);
907 string doc = tsandesh->
get_doc();
909 if ((index = doc.find_first_of(
"@")) != string::npos) {
911 f_out << doc.substr(0, index) <<
"<p/>" << endl;
912 string fdoc(doc.substr(index + 1));
914 f_out <<
"<table>" << endl;
915 print_sandesh_message(tsandesh, f_out);
919 boost::char_separator<char> fsep(
"@");
921 BOOST_FOREACH(
const string &f, ftokens) {
925 if ((lindex = f.find_first_of(
": \t")) != string::npos) {
926 string type(f.substr(0, lindex));
928 f_out <<
"<tr><th>" <<
type <<
"</th>";
929 if (lindex + 1 < f.size() && f.at(lindex) != f.at(lindex + 1) &&
930 (f.at(lindex + 1) ==
':' || f.at(lindex + 1) ==
'\t' ||
931 f.at(lindex + 1) ==
' ')) {
934 string content(f.substr(lindex + 1));
935 f_out <<
"<td>" << content <<
"</td></tr>" << endl;
937 f_out <<
"<td>" << f <<
"</td>" << endl;
941 f_out << doc <<
"<p/>" << endl;
942 print_sandesh_message_table(tsandesh, f_out);
945 f_out <<
"</table><br/>" << endl;
948 print_sandesh_message_table(tsandesh, f_out);
961 len = 6 + print_type(((
t_list*)ttype)->get_elem_type(), f_out);
963 }
else if (ttype->
is_set()) {
965 len = 5 + print_type(((
t_set*)ttype)->get_elem_type(), f_out);
967 }
else if (ttype->
is_map()) {
969 len = 5 + print_type(((
t_map*)ttype)->get_key_type(), f_out);
971 len += print_type(((
t_map*)ttype)->get_val_type(), f_out);
975 f_out << (((
t_base_type*)ttype)->is_binary() ?
"binary" : ttype->get_name());
976 len = ttype->get_name().size();
979 string type_name = ttype->
get_name();
980 f_out <<
"<a href=\"" << prog_name <<
".html#";
990 f_out << type_name <<
"\">";
991 len = type_name.size();
993 f_out << prog_name <<
".";
994 len += prog_name.size() + 1;
996 f_out << type_name <<
"</a>";
1015 f_out <<
'"' << get_escaped_string(tvalue) <<
'"';
1020 map<t_const_value*, t_const_value*> map_elems = tvalue->
get_map();
1021 map<t_const_value*, t_const_value*>::iterator map_iter;
1022 for (map_iter = map_elems.begin(); map_iter != map_elems.end(); map_iter++) {
1027 print_const_value(map_iter->first, f_out);
1029 print_const_value(map_iter->second, f_out);
1037 vector<t_const_value*> list_elems = tvalue->
get_list();;
1038 vector<t_const_value*>::iterator list_iter;
1039 for (list_iter = list_elems.begin(); list_iter != list_elems.end(); list_iter++) {
1044 print_const_value(*list_iter, f_out);
1061 string name = ttypedef->
get_name();
1062 f_out <<
"<div class=\"definition\">";
1063 f_out <<
"<h3 id=\"Typedef_" << name <<
"\">Typedef: " << name
1065 f_out <<
"<p><strong>Base type:</strong> ";
1066 print_type(ttypedef->
get_type(), f_out);
1067 f_out <<
"</p>" << endl;
1068 print_doc(ttypedef, f_out);
1069 f_out <<
"</div>" << endl;
1079 f_out <<
"<div class=\"definition\">";
1080 f_out <<
"<h3 id=\"Enum_" << name <<
"\">Enumeration: " << name
1082 print_doc(tenum, f_out);
1084 vector<t_enum_value*>::iterator val_iter;
1085 f_out <<
"<br/><table>" << endl;
1086 for (val_iter = values.begin(); val_iter != values.end(); ++val_iter) {
1087 f_out <<
"<tr><td><code>";
1088 f_out << (*val_iter)->get_name();
1089 f_out <<
"</code></td><td><code>";
1090 f_out << (*val_iter)->get_value();
1091 f_out <<
"</code></td></tr>" << endl;
1093 f_out <<
"</table></div>" << endl;
1101 f_out <<
"<tr id=\"Const_" << name <<
"\"><td><code>" << name
1102 <<
"</code></td><td><code>";
1103 print_type(tconst->
get_type(), f_out);
1104 f_out <<
"</code></td><td><code>";
1105 print_const_value(tconst->
get_value(), f_out);
1106 f_out <<
"</code></td></tr>";
1108 f_out <<
"<tr><td colspan=\"3\"><blockquote>";
1109 print_doc(tconst, f_out);
1110 f_out <<
"</blockquote></td></tr>";
1115 vector<t_const*>::iterator c_iter;
1116 for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
1117 generate_const(*c_iter, f_out);
1122 if (stat_table_created_ ==
false) {
1123 stat_table_created_ =
true;
1124 f_stats_tables_ <<
"{\n\"stat_type\":\"" << type <<
"\"," << endl;
1126 f_stats_tables_ <<
",\n{\n\"stat_type\":\"" << type <<
"\"," << endl;
1128 f_stats_tables_ <<
"\"stat_attr\":\"" << attr <<
"\"," << endl;
1129 f_stats_tables_ <<
"\"display_name\":\"" << display_name <<
"\"," << endl;
1130 f_stats_tables_ <<
"\"obj_table\": \"" << table_name <<
"\",\n";
1131 f_stats_tables_ <<
"\"attributes\":[" << endl;
1132 first_member_ =
true;
1136 map<string, string>::iterator jt;
1137 string uve_type =
"";
1140 string annotations = jt->second;
1141 boost::char_separator<char> fsep(
",");
1143 BOOST_FOREACH(
const string &tag, tags) {
1144 size_t index = tag.find(
':');
1145 if(index != string::npos) {
1146 string fname = tag.substr(0, index);
1148 uve_type = tag.substr(index+1);
1149 boost::trim(uve_type);
1158 template <
typename T>
1161 vector<t_field*>::const_iterator m_iter;
1162 if (!boost::starts_with(name,
".")) {
1164 const vector<t_field*>& tmembers = tstruct->get_members();
1165 for (m_iter = tmembers.begin(); m_iter != tmembers.end(); ++m_iter) {
1166 map<string, string>::iterator jt;
1167 if (name == (*m_iter)->get_name()) {
1168 return get_datatype_from_tfield((*m_iter)->get_type());
1171 }
else if (name.compare(
".__key") == 0) {
1174 return get_datatype_from_tfield(keytype);
1177 const vector<t_field*>& tmembers = cstruct->
get_members();
1178 for (m_iter = tmembers.begin(); m_iter != tmembers.end(); ++m_iter) {
1179 map<string, string>::iterator jt;
1180 if (name.substr(1) == (*m_iter)->get_name()) {
1181 return get_datatype_from_tfield((*m_iter)->get_type());
1188 template <
typename T>
1190 string>& top_level_tags, vector<string>& schema,
t_field* tfield) {
1191 BOOST_FOREACH(
const string &tag, top_level_tags) {
1193 const vector<t_field*>& tmembers = tstruct->get_members();
1194 vector<t_field*>::const_iterator m_iter;
1195 for (m_iter = tmembers.begin(); m_iter != tmembers.end(); ++m_iter) {
1196 map<string, string>::iterator jt;
1197 if (tag == (*m_iter)->get_name()) {
1199 schema.push_back(generate_stat_schema_struct_base_member(
1200 fname, *m_iter,
"true", tfield));
1207 template <
typename T>
1210 vector<string> >& suffixes, vector<string>& schemas) {
1211 map<string, vector<string> >::iterator it;
1212 for (it=suffixes.begin(); it!=suffixes.end(); ++it) {
1213 string fname = it->first;
1214 string datatype = get_type_of_member(fname, tfield, cstruct, tstruct);
1215 if (boost::starts_with(fname,
".")) {
1216 fname = tfield->
get_name() + fname;
1218 if (!prefix.empty()) {
1219 fname = prefix +
"." + fname;
1221 string index =
"true";
1223 vector<string>::iterator name_it;
1224 for (name_it = it->second.begin(); name_it!=it->second.end(); ++name_it) {
1225 string suffix_name = tfield->
get_name() + *name_it;
1226 if (boost::starts_with(suffix_name,
".")) {
1227 suffix_name = tfield->
get_name() + suffix_name;
1229 if (!prefix.empty()) {
1230 suffix_name = prefix +
"." + suffix_name;
1232 if(name_it == it->second.begin()) {
1233 suffix = suffix +
"\"" + suffix_name +
"\"";
1235 suffix = suffix +
", \"" + suffix_name +
"\"";
1239 f_stats_tables_ <<
"," << endl;
1240 string uve_type = get_uve_type(it->first, tfield);
1241 std::ostringstream oss;
1242 if (uve_type !=
"") {
1243 oss <<
"{\"name\":\"" << fname <<
1244 "\",\"datatype\":\"" << datatype <<
"\",\"index\":" << index <<
1245 ",\"uve_type\":\"" << uve_type <<
1246 "\",\"suffixes\":[" << suffix <<
"]}";
1248 oss <<
"{\"name\":\"" << fname <<
1249 "\",\"datatype\":\"" << datatype <<
"\",\"index\":" << index <<
1250 ",\"suffixes\":[" << suffix <<
"]}";
1252 schemas.push_back(oss.str());
1253 indent(f_stats_tables_) << oss.str();
1259 vector<string> tags, map<
string, vector<string> > suffixes,
1260 string& index,
bool& is_suffixed_field,
bool& is_tag) {
1261 BOOST_FOREACH(
const string &tag, tags) {
1262 string field_name = string(
".") + fname;
1263 string trimmed_tag = tag;
1264 boost::trim(trimmed_tag);
1265 if (trimmed_tag == field_name) {
1270 for(map<
string, vector<string> >::iterator it = suffixes.begin(); it != suffixes.end(); ++it) {
1271 string field_name = string(
".") + fname;
1272 string trimmed_tag = it->first;
1273 boost::trim(trimmed_tag);
1274 if (trimmed_tag == field_name) {
1275 is_suffixed_field =
true;
1279 for(map<
string, vector<string> >::iterator it = suffixes.begin(); it != suffixes.end(); ++it) {
1280 string field_name = string(
".") + fname;
1281 vector<string> values = it->second;
1282 BOOST_FOREACH(
string value, values) {
1283 if (value == field_name) {
1293 map<
string, vector<string> > suffixes, vector<string>& schemas) {
1294 const vector<t_field*> members = tstruct->
get_members();
1295 vector<t_field*>::const_iterator m_iter;
1297 if(!prefix.empty()) {
1298 prefix = prefix +
"." + name;
1302 for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
1303 string index =
"false";
1304 bool is_suffixed_field =
false, is_tag =
false, is_index =
false;
1305 is_indexed_or_suffixed_field((*m_iter)->get_name(), tags, suffixes, index, is_suffixed_field, is_tag);
1306 if (index ==
"true") {
1311 if (is_suffixed_field) {
1314 t_type* mtype = (*m_iter)->get_type();
1316 string schema = generate_stat_schema_struct_base_member(prefix, *m_iter, index, tfield);
1317 if (index ==
"true" || is_tag)
1318 schemas.push_back(schema);
1320 string mtype_name = mtype->
get_name();
1321 t_struct *cstruct = find_struct_with_name(mtype_name);
1323 generate_stat_schema_struct(prefix, (*m_iter), cstruct, tstruct,
false, schemas);
1327 generate_stat_schema_list(prefix, etype, (*m_iter), tstruct,
false, is_index, schemas);
1328 }
else if (mtype->
is_map()) {
1329 t_type* valtype= ((
t_map*)((*m_iter)->get_type()))->get_val_type();
1330 t_type* keytype= ((
t_map*)((*m_iter)->get_type()))->get_key_type();
1331 generate_stat_schema_map(prefix, keytype, valtype, (*m_iter), tstruct,
false, is_index, schemas);
1337 string datatype = ttype->
get_name();
1338 if ((datatype ==
"u32") || (datatype ==
"u16") || (datatype ==
"u64"))
1345 if (!first_member_) {
1346 f_stats_tables_ <<
"," << endl;
1348 std::ostringstream oss;
1349 if (uve_type !=
"") {
1350 oss <<
"{\"name\":\"" << name <<
"\",\"datatype\":\""
1351 << datatype <<
"\",\"index\":" << index <<
",\"uve_type\":\""
1352 << uve_type <<
"\"}";
1354 oss <<
"{\"name\":\"" << name <<
"\",\"datatype\":\""
1355 << datatype <<
"\",\"index\":" << index <<
"}";
1357 string schema = oss.str();
1358 indent(f_stats_tables_) << schema;
1359 first_member_ =
false;
1364 template <
typename T>
1366 map<string, vector<string> > suffixes;
1367 vector<string> top_level_tags;
1368 vector<string> member_tags;
1369 bool is_empty_tag =
false;
1370 map<string, string>::iterator jt;
1374 is_empty_tag =
true;
1375 if (!is_top_level && !is_empty_tag && !is_index) {
1378 if(!prefix.empty()) {
1379 tname = prefix +
"." + tname;
1381 if (is_empty_tag ==
false) {
1382 extract_tags(tfield, suffixes, top_level_tags, member_tags);
1385 string name = tname + string(
".__key");
1386 string datatype = get_datatype_from_tfield(keytype);
1387 string index =
"false";
1388 bool is_suffixed_field =
false, is_tag =
false;
1389 is_indexed_or_suffixed_field(
string(
"__key"), member_tags, suffixes, index, is_suffixed_field, is_tag);
1390 string uve_type = get_uve_type(
"__key", tfield);
1391 if (!is_suffixed_field) {
1392 string schema = generate_table_entry(name, datatype, index, uve_type);
1393 if (index ==
"true" || is_tag)
1394 schemas.push_back(schema);
1397 name = tname + string(
".__value");
1398 datatype = get_datatype_from_tfield(valtype);
1400 BOOST_FOREACH(
const string &f, member_tags) {
1401 if (f ==
string(
".__value")) {
1405 uve_type = get_uve_type(
"__value", tfield);
1406 generate_table_entry(name, datatype, index, uve_type);
1410 string name = tname +
".*";
1411 string datatype = get_datatype_from_tfield(valtype);
1412 string index =
"false";
1416 string uve_type = get_uve_type(tname, tfield);
1417 string schema = generate_table_entry(name, datatype, index, uve_type);
1418 if (index ==
"true") {
1419 schemas.push_back(schema);
1425 uve_type = get_uve_type(tname, tfield);
1426 schema = generate_table_entry(name, datatype, index, uve_type);
1429 string empty_prefix;
1431 string sname = valtype->
get_name();
1432 t_struct *cstruct = find_struct_with_name(sname);
1435 generate_stat_schema_struct_members(empty_prefix, tfield, cstruct, member_tags, suffixes, schemas);
1437 generate_stat_schema_toplevel_tags(tstruct, top_level_tags, schemas, tfield);
1438 generate_stat_schema_suffixes(empty_prefix, tfield, cstruct, tstruct, suffixes, schemas);
1441 generate_stat_schema_toplevel_tags(tstruct, top_level_tags, schemas, tfield);
1442 generate_stat_schema_suffixes(empty_prefix, tfield, NULL, tstruct, suffixes, schemas);
1450 if (!prefix.empty()) {
1451 uve_type = get_uve_type(
"." + fname, top_field);
1452 fname = prefix+
"." + fname;
1454 uve_type = get_uve_type(fname, top_field);
1456 string datatype = get_datatype_from_tfield(tfield->
get_type());
1457 return generate_table_entry(fname, datatype, index, uve_type);
1460 template <
typename T>
1462 &suffixes, vector<string> &top_level_tags, vector<string> &member_tags) {
1463 boost::char_separator<char> fsep(
",");
1464 tokenizer tags(tfield->annotations_[
"tags"], fsep);
1465 BOOST_FOREACH(
const string &tag, tags) {
1466 size_t index = tag.find(
':');
1467 if(index != string::npos) {
1468 string fname = tag.substr(0, index);
1470 string suffix_name = tag.substr(index+1);
1471 boost::trim(suffix_name);
1472 if(suffixes.find(fname) == suffixes.end()) {
1473 vector<string> new_suffix;
1474 new_suffix.push_back(suffix_name);
1475 suffixes.insert(make_pair(fname, new_suffix));
1477 vector<string> old_suffixes = suffixes[fname];
1478 old_suffixes.push_back(suffix_name);
1479 suffixes[fname] = old_suffixes;
1482 string trimmed_tag = tag;
1483 boost::trim(trimmed_tag);
1484 if (!boost::starts_with(trimmed_tag,
".")) {
1485 top_level_tags.push_back(trimmed_tag);
1487 member_tags.push_back(trimmed_tag);
1493 template <
typename T>
1495 map<string, vector<string> > suffixes;
1496 vector<string> top_level_tags;
1497 vector<string> member_tags;
1498 bool is_empty_tag =
false;
1500 extract_tags(tfield, suffixes, top_level_tags, member_tags);
1502 map<string, string>::iterator jt = tfield->
annotations_.find(
"tags");
1504 is_empty_tag =
true;
1509 if(is_empty_tag || is_top_level)
1510 generate_stat_schema_struct_members(prefix, tfield, cstruct, member_tags, suffixes, schemas);
1511 generate_stat_schema_toplevel_tags(tstruct, top_level_tags, schemas, tfield);
1512 generate_stat_schema_suffixes(prefix, tfield, cstruct, tstruct, suffixes, schemas);
1515 template <
typename T>
1519 t_struct *cstruct = find_struct_with_name(sname);
1521 generate_stat_schema_struct(name, tfield, cstruct, tstruct, is_top_level, schemas);
1524 map<string, vector<string> > suffixes;
1525 vector<string> top_level_tags;
1526 vector<string> member_tags;
1527 bool is_empty_tag =
false;
1528 map<string, string>::iterator jt;
1532 is_empty_tag =
true;
1533 if (!is_top_level && !is_empty_tag && !is_index) {
1537 tname = name +
"." + tname;
1539 if (is_empty_tag ==
false) {
1540 extract_tags(tfield, suffixes, top_level_tags, member_tags);
1548 string index =
"false";
1549 bool is_suffixed_field =
false, is_tag =
false;
1550 is_indexed_or_suffixed_field(tname, member_tags, suffixes, index, is_suffixed_field, is_tag);
1557 string uve_type =
"";
1559 uve_type = jt->second;
1560 if (!is_suffixed_field) {
1561 string schema = generate_table_entry(tname, datatype, index, uve_type);
1562 if (is_tag || index ==
"true")
1563 schemas.push_back(schema);
1569 t_struct *cstruct = program_->get_struct(sname.c_str());
1574 const vector<t_program*>& includes = program_->get_includes();
1575 vector<t_program*>::const_iterator iter;
1576 for (iter = includes.begin(); iter != includes.end(); ++iter) {
1577 cstruct = (*iter)->get_struct(sname.c_str());
1585 template <
typename T>
1588 t_type* ltype= ((
t_list*)((tfield)->get_type()))->get_elem_type();
1589 generate_stat_schema_list(prefix, ltype, tfield, tsandesh,
true,
false, tags);
1593 generate_stat_schema_map(prefix, keytype, valtype, tfield, tsandesh,
true,
false, tags);
1595 string sname = (tfield->
get_type())->get_name();
1596 t_struct *cstruct = find_struct_with_name(sname);
1598 generate_stat_schema_struct(prefix, tfield, cstruct, tsandesh,
true, tags);
1604 string obj_table_name;
1605 vector<t_field*>::const_iterator m_iter;
1606 for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
1607 map<string, string>::iterator jt;
1608 if((*m_iter)->get_name() ==
"name") {
1609 jt = (*m_iter)->annotations_.find(
"key");
1610 if (jt != (*m_iter)->annotations_.end()) {
1611 return (*m_iter)->annotations_[
"key"];
1615 return obj_table_name;
1618 template <
typename T>
1621 string sname = valtype->
get_name();
1622 find_recursive_tags_struct(tsandesh, tfield, table, sname, prefix, schemas);
1626 template <
typename T>
1630 find_recursive_tags_struct(tsandesh, tfield, table, sname, prefix, schemas);
1634 template <
typename T>
1636 t_struct *cstruct = find_struct_with_name(sname);
1638 const vector<t_field*> members = cstruct->
get_members();
1639 generate_stat_tables_schema(tsandesh, members, table, prefix, schemas);
1643 template <
typename T>
1647 t_type* ltype= ((
t_list*)((tfield)->get_type()))->get_elem_type();
1648 find_recursive_tags_list(tsandesh, tfield, table, ltype, fname, index_schemas);
1652 find_recursive_tags_map(tsandesh, tfield, table, keytype, valtype, fname, index_schemas);
1654 string sname = (tfield->
get_type())->get_name();
1655 find_recursive_tags_struct(tsandesh, tfield, table, sname, fname, index_schemas);
1661 string doc = tfield->
get_doc();
1663 string display_name;
1664 if ((index = doc.find_first_of(
"@")) != string::npos) {
1665 boost::char_separator<char> fsep(
"@");
1667 BOOST_FOREACH(
const string &f, ftokens) {
1669 if ((lindex = f.find_first_of(
": \t")) != string::npos) {
1670 string attr_name = f.substr(0, lindex);
1671 boost::trim(attr_name);
1672 if(attr_name ==
"display_name") {
1673 string dn = f.substr(lindex+1);
1674 display_name = dn.substr(0, dn.find_first_of(
'\n'));
1675 boost::trim(display_name);
1676 return display_name;
1681 return display_name;
1684 template <
typename T>
1686 vector<t_field*>::const_iterator m_iter;
1687 string oname = tsandesh->get_name();
1688 for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
1689 map<string, string>::iterator jt;
1690 jt = (*m_iter)->annotations_.find(
"tags");
1691 if (jt != (*m_iter)->annotations_.end()) {
1692 string fname = (*m_iter)->get_name();
1693 if (!prefix.empty())
1694 fname = prefix +
"." + fname;
1695 string display_name = get_display_name_from_comments(*m_iter);
1696 generate_stat_table_schema_header(oname, fname, table, display_name);
1697 vector<string> new_tags;
1698 generate_stat_table_schema(oname, *m_iter, tsandesh, prefix, new_tags);
1699 for (
int i = 0; i < tags.size(); i++) {
1700 if (tags[i][0] !=
',')
1701 f_stats_tables_ <<
"," << endl;
1703 indent(f_stats_tables_) << tags[i];
1706 f_stats_tables_ <<
"\n]\n}";
1707 find_recursive_tags(tsandesh, *m_iter, table, fname, new_tags);
1714 const vector<t_field*> members = tsandesh->
get_members();
1715 string empty_prefix;
1716 vector<string> empty_tag;
1718 t_struct* data = program_->get_struct(members.front()->get_type()->get_name().c_str());
1719 const vector<t_field*> tmembers = data->
get_members();
1720 string obj_table_name = find_obj_table_name(tmembers);
1721 generate_stat_tables_schema(data, tmembers, obj_table_name, empty_prefix, empty_tag);
1723 string obj_table_name =
"NONE";
1724 generate_stat_tables_schema(tsandesh, members, obj_table_name, empty_prefix, empty_tag);
1734 vector<t_field*> members = tstruct->
get_members();
1735 vector<t_field*>::iterator mem_iter = members.begin();
1737 f_out <<
"<tr><th>Key</th><th>Field</th><th>Type</th><th>Description</th><th>Requiredness</th><th>Default value</th></tr>"
1739 for ( ; mem_iter != members.end(); mem_iter++) {
1740 f_out <<
"<tr><td>" << (*mem_iter)->get_key() <<
"</td><td>";
1741 f_out << (*mem_iter)->get_name();
1742 f_out <<
"</td><td>";
1743 print_type((*mem_iter)->get_type(), f_out);
1744 f_out <<
"</td><td>";
1745 f_out << (*mem_iter)->get_doc();
1746 f_out <<
"</td><td>";
1748 f_out <<
"optional";
1750 f_out <<
"required";
1754 f_out <<
"</td><td>";
1756 if (default_val != NULL) {
1757 print_const_value(default_val, f_out);
1759 f_out <<
"</td></tr>" << endl;
1761 f_out <<
"</table><br/>";
1771 f_out <<
"<div class=\"definition\">";
1772 f_out <<
"<h3 id=\"Struct_" << name <<
"\">";
1773 f_out <<
"Struct: ";
1774 f_out << name <<
"</h3>" << endl;
1775 generate_struct_table(tstruct, f_out);
1776 print_doc(tstruct, f_out);
1782 string doc = tsandesh->
get_doc();
1784 string cli_name =
"", cli_help =
"";
1785 if ((index = doc.find_first_of(
"@")) != string::npos) {
1786 string fdoc(doc.substr(index + 1));
1788 boost::char_separator<char> fsep(
"@");
1790 BOOST_FOREACH(
const string &f, ftokens) {
1794 if ((lindex = f.find_first_of(
": \t")) != string::npos) {
1795 string type(f.substr(0, lindex));
1796 if (lindex + 1 < f.size() && f.at(lindex) != f.at(lindex + 1) &&
1797 (f.at(lindex + 1) ==
':' || f.at(lindex + 1) ==
'\t' ||
1798 f.at(lindex + 1) ==
' ')) {
1801 string content(f.substr(lindex + 1));
1802 content.erase(content.length()-1);
1803 if (boost::starts_with(
type,
"cli_name")) {
1805 }
else if (boost::starts_with(
type,
"description")) {
1814 f_out <<
"," << endl;
1820 indent(f_out) <<
"\"" << tsandesh->
get_name() <<
"\" : {" << endl;
1821 indent(f_out) <<
"\"" << cli_name <<
"\" : " <<
"{ \"" << cli_help <<
"\" :" << endl;
1822 vector<t_field*> members = tsandesh->
get_members();
1823 int size = members.size();
1825 indent(f_out) <<
"[ " << endl;
1827 BOOST_FOREACH(
t_field *tfield, members) {
1828 indent(f_out) <<
"[\"" << tfield->
get_name();
1829 string field_doc =
"\"\"";
1830 if (!tfield->
get_doc().empty()) {
1831 field_doc = tfield->
get_doc();
1832 field_doc.erase(field_doc.length()-1);
1833 field_doc =
"\""+field_doc+
"\"";
1835 f_out <<
"\", " << field_doc <<
"]";
1842 indent(f_out) <<
"]}}";
1855 f_out <<
"<h3 id=\"Snh_" << sandesh_name_ <<
"\"> "
1856 << sandesh_name_ <<
"</h3>" << endl;
1857 print_sandesh(tsandesh, f_out);
1858 vector<t_field*> members = tsandesh->
get_members();
1860 f_out <<
"<tr><th>Field</th><th>Type</th><th>Description</th></tr>"
1862 BOOST_FOREACH(
t_field *tfield, members) {
1863 if (tfield->get_auto_generated()) {
1867 if (type->is_static_const_string()) {
1870 f_out <<
"<tr><td>" << tfield->
get_name() <<
"</td><td>";
1871 print_type(tfield->
get_type(), f_out);
1872 f_out <<
"</td><td>";
1874 f_out <<
"</td></tr>" << endl;
1876 f_out <<
"</table><br/>";
1885 vector<t_field*> smembers = tsandesh->
get_members();
1886 if (smembers.size() == 1 && smembers[0]->get_type()->is_struct()) {
1887 sandesh_name_ = smembers[0]->get_type()->get_name();
1888 boost::trim(sandesh_name_);
1889 f_out <<
"<h3 id=\"Snh_" << sandesh_name_ <<
"\"> "
1890 << sandesh_name_ <<
"</h3>" << endl;
1891 print_sandesh(tsandesh, f_out);
1892 t_struct *cstruct = find_struct_with_name(sandesh_name_);
1894 f_out <<
"</table><br/>";
1897 generate_struct_table(cstruct, f_out);
t_doc_generator(t_program *program, const map< string, string > &parsed_options, const string &option_string)
void generate_struct(t_struct *tstruct)
void find_recursive_tags_list(T *, t_field *, string, t_type *, string, vector< string > &)
void generate_stat_schema_struct_members(string name, t_field *, t_struct *, vector< string >, map< string, vector< string > >, vector< string > &)
virtual bool is_xception() const
bool f_introspect_initialized_
const std::string & get_name() const
void print_doc_string(string doc, ofstream &f_out)
t_type * get_type() const
string get_uve_type(string, t_field *)
string generate_stat_schema_struct_base_member(string, t_field *, string, t_field *)
void find_recursive_tags_struct(T *, t_field *, string, string, string, vector< string > &)
void print_sandesh(t_sandesh *tdoc, ofstream &f_out)
void generate_stat_table_schema_header(string, string, string, string)
void generate_stat_schema_map(string, t_type *, t_type *, t_field *, T *, bool, bool, vector< string > &)
void generate_stat_tables_schema(t_sandesh *)
void generate_service(t_service *tservice)
void is_indexed_or_suffixed_field(string, vector< string >, map< string, vector< string > >, string &, bool &, bool &)
void print_sandesh_message(t_sandesh *tdoc, ofstream &f_out)
string get_doc_file_description(doc_ftype::type dtype)
bool generate_introspect_cli(t_sandesh *, ofstream &f_out, bool &first_file)
bool f_log_invalid_initialized_
virtual bool is_map() const
const std::string & get_name() const
string get_display_name_from_comments(t_field *)
bool f_log_info_initialized_
void generate_sandesh_program_doc_schema_uve(t_program *tprog, ofstream &f_out, string fsuffix)
void print_const_value(t_const_value *tvalue, ofstream &f_out)
void generate_sandesh(t_sandesh *tsandesh)
virtual bool is_enum() const
t_type * get_type() const
virtual bool is_base_type() const
void generate_struct_table(t_struct *tstruct, ofstream &f_out)
t_struct * find_struct_with_name(string sname)
bool f_log_alert_initialized_
void generate_stat_schema_struct(string, t_field *, t_struct *, T *, bool, vector< string > &)
bool generate_sandesh_program(doc_ftype::type dtype)
void find_recursive_tags_map(T *, t_field *, string, t_type *, t_type *, string, vector< string > &)
void generate_stat_schema_suffixes(string, t_field *, t_struct *, T *, map< string, vector< string > > &, vector< string > &)
const std::map< t_const_value *, t_const_value * > & get_map() const
const members_type & get_members()
void generate_stats_schema_program()
string get_doc_member(t_sandesh *tsandesh, string member)
int64_t get_integer() const
bool f_log_notice_initialized_
void generate_doc_type(ofstream &f_out)
t_const_value_type get_type() const
string get_datatype_from_tfield(t_type *tfield)
virtual bool is_container() const
virtual bool is_typedef() const
t_type * get_type() const
bool f_trace_initialized_
void generate_enum(t_enum *tenum)
virtual bool is_set() const
bool f_log_error_initialized_
std::string get_name() const
string get_object_type(t_sandesh *tsandesh)
boost::tokenizer< boost::char_separator< char > > tokenizer
bool f_log_emerg_initialized_
t_const_value * get_value() const
bool f_log_debug_initialized_
void generate_sandesh_uve(t_sandesh *tsandesh, ofstream &f_out)
void generate_consts(vector< t_const * > consts, ofstream &f_out)
string sandesh_level_to_string(const sandesh_level::type &slevel)
string get_type_of_member(string, t_field *, t_struct *, T *)
virtual const std::string & get_name() const
virtual bool is_list() const
void generate_const_enum_typedef_object_program()
const std::vector< t_enum_value * > & get_constants()
void generate_typedef(t_typedef *ttypedef)
void print_doc(t_doc *tdoc, ofstream &f_out)
double get_double() const
void generate_program_toc(ofstream &f_out, string fsuffix, doc_ftype::type dtype)
t_program * get_program()
virtual bool is_struct() const
void generate_const(t_const *tconst)
sandesh_level::type get_sandesh_level(t_sandesh *tsandesh)
const std::string & get_doc() const
const t_type * get_type()
void extract_tags(T *, map< string, vector< string > > &, vector< string > &, vector< string > &)
bool f_log_crit_initialized_
bool is_sandesh_type(t_sandesh *tsandesh, doc_ftype::type dtype)
string get_doc_file_suffix(doc_ftype::type dtype)
bool f_log_warn_initialized_
string generate_table_entry(string name, string datatype, string index, string)
void generate_stat_table_schema(string, t_field *, T *, string, vector< string > &)
void find_recursive_tags(T *, t_field *, string, string, vector< string > &)
int print_type(t_type *ttype, ofstream &f_out)
bool generate_sandesh_program_doc(t_program *tprog, ofstream &f_out, string fsuffix, doc_ftype::type dtype)
t_const_value * get_value()
void generate_sandesh_program_doc_schema(t_program *tprog, ofstream &f_out, string fsuffix, doc_ftype::type dtype)
string find_obj_table_name(const vector< t_field * >)
void generate_stat_schema_list(string, t_type *, t_field *, T *, bool, bool, vector< string > &)
std::map< std::string, std::string > annotations_
virtual bool is_service() const
void print_sandesh_message_table(t_sandesh *tdoc, ofstream &f_out)
void generate_program_toc_row(t_program *tprog, ofstream &f_out, string fsuffix, doc_ftype::type dtype)
#define THRIFT_REGISTER_GENERATOR(language, long_name, doc)
void generate_stat_schema_toplevel_tags(T *, vector< string > &, vector< string > &, t_field *)
sandesh_level::type string_to_sandesh_level(const string &level)
const std::vector< t_const_value * > & get_list() const