Flow123d  master-f44eb46
type_output.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file type_output.cc
15  * @brief
16  */
17 
18 #include <string>
19 #include <regex>
20 
21 #include "system/exceptions.hh" // for ExcUnknownDesc...
22 #include "input/type_output.hh"
23 #include "input/type_repository.hh"
24 #include "input/type_generic.hh"
25 #include "input/type_tuple.hh"
26 #include "input/type_selection.hh"
27 
28 #include <boost/algorithm/string/replace.hpp>
29 #include <boost/tokenizer.hpp> // for tokenizer<>::i...
30 #include <boost/functional/hash.hpp>
31 
32 
33 
34 namespace Input {
35 namespace Type {
36 
37 using namespace std;
38 
39 
40 /*******************************************************************
41  * implementation of OutputBase
42  */
43 
45 
46 
47 
49 {}
50 
51 
52 
53 void OutputBase::get_integer_bounds(Integer integer, int &lower , int &upper ) {
54  lower = integer.lower_bound_;
55  upper = integer.upper_bound_;
56 }
57 
58 
59 
60 void OutputBase::get_double_bounds(Double dbl, double &lower , double &upper ) {
61  lower = dbl.lower_bound_;
62  upper = dbl.upper_bound_;
63 }
64 
65 
66 
67 void OutputBase::get_array_sizes(Array array, unsigned int &lower , unsigned int &upper ) {
68  lower = array.data_->lower_bound_;
69  upper = array.data_->upper_bound_;
70 }
71 
72 
73 
74 void OutputBase::get_array_type(Array array, std::shared_ptr<TypeBase> &arr_type) {
75  arr_type = array.data_->type_of_values_;
76 }
77 
78 
79 
80 const string & OutputBase::get_record_description(const Record *rec) {
81  return rec->data_->description_;
82 }
83 
84 
85 
86 const string & OutputBase::get_abstract_description(const Abstract *a_rec) {
87  return a_rec->child_data_->description_;
88 }
89 
90 
91 
92 void OutputBase::get_parent_vec(Record rec, std::vector< std::shared_ptr<Abstract> > &parent_vec) {
93  parent_vec = rec.data_->parent_vec_;
94 }
95 
96 
97 
98 void OutputBase::get_default(Record::KeyIter it, string &type, string &value) {
99  value = it->default_.value_;
100  if ( it->default_.is_obligatory() ) {
101  type = "obligatory";
102  } else if ( it->default_.is_optional() ) {
103  type = "optional";
104  } else if ( it->default_.has_value_at_read_time() ) {
105  type = "value at read time";
106  } else {
107  type = "value at declaration";
108  }
109 
110 }
111 
112 
114  return sel->data_->description_;
115 }
116 
117 
118 void OutputBase::get_adhoc_parent_name(const AdHocAbstract *a_rec, string &parent_name) {
119  parent_name = a_rec->ancestor_.type_name();
120 }
121 
122 
124  return a_rec->ancestor_.child_data_->list_of_childs.begin();
125 }
126 
127 template <class T>
128 void OutputBase::print_generic(ostream& stream, const TypeBase *type) {
129  // print possible generic
131  const T *gen_type = Input::TypeRepository<T>::get_instance().find_hash(type->generic_type_hash_).get();
132  ASSERT(gen_type)(type->hash_str())(type->type_name());
133  print_base(stream, gen_type);
134  }
135 }
136 void OutputBase::print_base(ostream& stream, const TypeBase *type) {
137 
138  ASSERT(type);
139 
140  if (typeid(*type) == typeid(Type::Tuple)) {
141  print_impl(stream, static_cast<const Type::Record *>(type) );
142  } else
143  if (typeid(*type) == typeid(Type::Record)) {
144  print_impl(stream, static_cast<const Type::Record *>(type) );
145  } else
146  if (typeid(*type) == typeid(Type::Array)) {
147  print_impl(stream, static_cast<const Type::Array *>(type) );
148  } else
149  if (typeid(*type) == typeid(Type::Abstract)) {
150  print_impl(stream, static_cast<const Type::Abstract *>(type) );
151  } else
152  if (typeid(*type) == typeid(Type::AdHocAbstract)) {
153  print_impl(stream, static_cast<const Type::AdHocAbstract *>(type) );
154  } else
155  if (typeid(*type) == typeid(Type::Selection)) {
156  print_impl(stream, static_cast<const Type::Selection *>(type) );
157  } else
158  if (typeid(*type) == typeid(Type::Integer)) {
159  print_impl(stream, static_cast<const Type::Integer *>(type) );
160  } else
161  if (typeid(*type) == typeid(Type::Double)) {
162  print_impl(stream, static_cast<const Type::Double *>(type) );
163  } else
164  if (typeid(*type) == typeid(Type::Bool)) {
165  print_impl(stream, static_cast<const Type::Bool *>(type) );
166  } else
167  if (typeid(*type) == typeid(Type::Parameter)) {
168  print_impl(stream, static_cast<const Type::Parameter *>(type) );
169  } else {
170  const Type::FileName * file_name_type = dynamic_cast<const Type::FileName *>(type);
171  if (file_name_type != NULL ) {
172  print_impl(stream, file_name_type );
173  return;
174  }
175 
176  const Type::String * string_type = dynamic_cast<const Type::String *>(type);
177  if (string_type != NULL ) {
178  print_impl(stream, string_type );
179  return;
180  }
181 
182  // default -> error
183  THROW( Type::ExcUnknownDescendant() << Type::EI_TypeName(typeid(type).name()) );
184  }
185 }
186 
187 
188 void OutputBase::write_default_value(std::ostream& stream, Default dft) {
189  if (dft.is_obligatory() || dft.is_optional()) {
190  stream << "<" << dft.value() << ">";
191  } else {
192  stream << "\"" << dft.value() << "\"";
193  }
194 }
195 
196 void OutputBase::write_description(std::ostream& stream, const string& str,
197  unsigned int padding, unsigned int hash_count) {
198  string s = str;
199  boost::replace_all(s, "\\$", "$");
200 
201  boost::tokenizer<boost::char_separator<char> > line_tokenizer(s, boost::char_separator<char>("\n"));
202  boost::tokenizer<boost::char_separator<char> >::iterator it;
203 
204  // For every \n add padding at beginning of the next line.
205  for(it = line_tokenizer.begin(); it != line_tokenizer.end(); ++it) {
206  stream << endl;
207  stream << setw(padding) << "";
208  stream << std::setfill('#') << setw(hash_count) << "" << std::setfill(' ') << " " << *it;
209  }
210 }
211 
212 
214  processed_types_hash_.clear();
215  full_hash_ = 0;
216 }
217 
218 
219 bool OutputBase::was_written(std::size_t hash)
220 {
221  bool in_set = ( processed_types_hash_.find(hash) != processed_types_hash_.end() );
222  if (! in_set) processed_types_hash_.insert(hash);
223  return in_set;
224 }
225 
227  TypeBase::TypeHash &generic_type_hash, TypeBase::json_string &parameter_map_to_json) {
228  attr_map = *( type->attributes_.get() );
229  generic_type_hash = type->generic_type_hash_;
230  if (type->parameter_map_.size()) {
231  parameter_map_to_json = type->print_parameter_map_to_json( type->parameter_map_ );
232  }
233 }
234 
235 
236 
237 
238 /*******************************************************************
239  * implementation of OutputText
240  */
241 
242 ostream& OutputText::print(ostream& stream) {
243  doc_type_ = full_record;
244  clear_processed_types();
245 
246  print_base(stream, type_);
247  return stream;
248 }
249 
250 void OutputText::print_impl(ostream& stream, const Record *type) {
251  ASSERT(type->is_finished())(type->type_name())(type->class_name()).warning("Printing documentation of unfinished type.");
252  switch (doc_type_) {
253  case key_record:
254  stream << "" << type->class_name() << " '" << type->type_name() << "' (" << type->size() << " keys).";
255  break;
256  case full_record:
257  TypeBase::TypeHash hash=type->content_hash();
258  if (! was_written(hash)) {
259  // header
260  stream << endl;
261  stream << "" << type->class_name() << " '" << type->type_name() << "'";
262  // parent record
263  /*std::shared_ptr<Abstract> parent_ptr;
264  get_parent_ptr(*type, parent_ptr);
265  if (parent_ptr) {
266  stream << ", implementation of " << parent_ptr->type_name();
267  }*/
268 
269  // reducible to key
270  Record::KeyIter key_it = type->auto_conversion_key_iter();
271  if (key_it != type->end()) {
272  stream << ", reducible to key '" << key_it->key_ << "'";
273  }
274  stream << "" << " (" << type->size() << " keys).";
275  write_description(stream, OutputBase::get_record_description(type), 0);
276  stream << endl;
277  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << endl;
278  // keys
279  doc_type_ = key_record;
280  for (Record::KeyIter it = type->begin(); it != type->end(); ++it) {
281  size_setw_ = it->key_.size() + 3;
282  stream << setw(padding_size) << "" << it->key_ << " = ";
283  write_default_value(stream, it->default_);
284  stream << endl;
285  stream << setw(padding_size + size_setw_) << "" <<"#### is ";
286  print_base(stream, it->type_.get());
287  write_description(stream, it->description_, padding_size+size_setw_);
288  stream << endl;
289  }
290  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << " " << type->type_name() << endl;
291  // Full documentation of embedded record types.
292  doc_type_ = full_record;
293  }
294  break;
295  }
296 }
297 void OutputText::print_impl(ostream& stream, const Array *type) {
298  std::shared_ptr<TypeBase> array_type;
299  get_array_type(*type, array_type);
300  switch (doc_type_) {
301  case key_record:
302  unsigned int lower_size, upper_size;
303  get_array_sizes(*type, lower_size, upper_size);
304  stream << "Array, size limits: [" << lower_size << ", " << upper_size << "] of type: " << endl;
305  stream << setw(padding_size + size_setw_) << "" << "#### ";
306  print_base(stream, array_type.get());
307  break;
308  case full_record:
309  print_base(stream, array_type.get());
310  break;
311  }
312 }
313 
314 
315 void OutputText::print_impl(ostream& stream, const Abstract *type) {
316  // Print documentation of abstract record
317  switch (doc_type_) {
318  case key_record:
319  stream << "Abstract '" << type->type_name() << "' with "<< type->child_size() << " descendants.";
320  break;
321  case full_record:
322  TypeBase::TypeHash hash=type->content_hash();
323  if (! was_written(hash) ) {
324  // header
325  stream << endl;
326  stream << "" << "Abstract '" << type->type_name() << "' with " << type->child_size() << " descendants.";
327  write_description(stream, OutputBase::get_abstract_description( type ), 0);
328  stream << endl;
329  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << endl;
330  // descendants
331  doc_type_ = key_record;
332  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
333  size_setw_ = 0;
334  stream << setw(padding_size) << "";
335  stream << "" << "Record '" << (*it).type_name() << "'";
336  write_description(stream, OutputBase::get_record_description( &(*it) ), padding_size+size_setw_);
337  stream << endl;
338  }
339  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << " " << type->type_name() << endl;
340  // Full documentation of embedded record types.
341  doc_type_ = full_record;
342  }
343  break;
344  }
345 }
346 
347 
348 void OutputText::print_impl(ostream& stream, const AdHocAbstract *type) {
349  // Print documentation of adhoc abstract record
350  if (doc_type_ == key_record) {
351  stream << type->class_name();
352  /*string parent_name;
353  get_adhoc_parent_name(type, parent_name);
354  stream << "AdHocAbstract" << endl;
355  stream << setw(padding_size + size_setw_) << "";
356  stream << "#### Derived from Abstract '" << parent_name << "', ";
357  stream << "added Records: ";
358  {
359  Abstract::ChildDataIter parent_it = get_adhoc_parent_data(type);
360  bool add_comma = false;
361  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
362  if ((*it).type_name() == (*parent_it).type_name()) {
363  ++parent_it;
364  } else {
365  if (add_comma) stream << ", ";
366  else add_comma = true;
367  stream << "'" << (*it).type_name() << "'";
368  }
369  }
370  }*/
371  }
372 }
373 void OutputText::print_impl(ostream& stream, const Selection *type) {
374  ASSERT(type->is_finished())(type->type_name()).warning("Printing documentation of unfinished Input::Type::Selection.");
375  switch (doc_type_) {
376  case key_record:
377  stream << "Selection '" << type->type_name() << "' of " << type->size() << " values.";
378  break;
379  case full_record:
380  TypeBase::TypeHash hash=type->content_hash();
381  if (! was_written(hash) ) {
382  stream << endl << "Selection '" << type->type_name() << "' of " << type->size() << " values.";
383  write_description(stream, OutputBase::get_selection_description( type ), 0);
384  stream << endl;
385  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << endl;
386  // keys
387  for (Selection::keys_const_iterator it = type->begin(); it != type->end(); ++it) {
388  stream << setw(padding_size) << "" << it->key_ << " = " << it->value;
389  if (it->description_ != "") {
390  stream << endl;
391  stream << setw(padding_size + it->key_.size() + 3) << "" << "# " << it->description_ << "";
392  }
393  stream << endl;
394  }
395  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << " " << type->type_name() << endl;
396  }
397  break;
398  }
399 }
400 void OutputText::print_impl(ostream& stream, const Integer *type) {
401  if (doc_type_ == key_record) {
402  int lower_bound, upper_bound;
403  get_integer_bounds(*type, lower_bound, upper_bound);
404  stream << "Integer in [" << lower_bound << ", " << upper_bound << "]";
405  }
406 }
407 void OutputText::print_impl(ostream& stream, const Double *type) {
408  if (doc_type_ == key_record) {
409  double lower_bound, upper_bound;
410  get_double_bounds(*type, lower_bound, upper_bound);
411  stream << "Double in [" << lower_bound << ", " << upper_bound << "]";
412  }
413 }
414 void OutputText::print_impl(ostream& stream, const Bool *type) {
415  if (doc_type_ == key_record) {
416  stream << type->class_name();
417  }
418 }
419 void OutputText::print_impl(ostream& stream, const String *type) {
420  if (doc_type_ == key_record) {
421  stream << type->class_name() + " (generic)";
422  }
423 }
424 void OutputText::print_impl(ostream& stream, const FileName *type) {
425  if (doc_type_ == key_record) {
426  stream << "FileName of ";
427  switch (type->get_file_type()) {
428  case ::FilePath::input_file:
429  stream << "input file";
430  break;
431  case ::FilePath::output_file:
432  stream << "output file";
433  break;
434  default:
435  stream << "file with unknown type";
436  break;
437  }
438  }
439 }
440 
441 
442 
443 void OutputText::print_impl(FMT_UNUSED ostream& stream, FMT_UNUSED const Parameter *type) {
444  ASSERT(false).error("Parameter appears in the IST. Check where Instance is missing.");
445 }
446 
447 
448 
449 
450 /*******************************************************************
451  * implementation of OutputJSONMachine
452  */
453 
455 : OutputBase()
456 {
457  rev_num_data_ = rev_num_data;
458 
459  format_head="{ \"version\" :";
460  format_inner=",\n\"ist_nodes\" : [\n";
461  format_full_hash="{}],\n";
462  format_tail="}\n";
463 }
464 
465 
466 
468 : OutputJSONMachine(rev_num_data)
469 {
470  root_type_ = root_type;
471  root_type_.finish();
472 }
473 
474 
475 std::string OutputJSONMachine::escape_description(std::string desc) {
476  static std::vector< std::pair<std::regex, std::string> > rewrite_rules = {
477  // replace single slash with two slashes
478  {std::regex("\\\\"), "\\\\"},
479  // replace quote with slash quote
480  {std::regex("\\\""), "\\\""},
481  // replace special chars with escaped slash + special chars
482  {std::regex("\\n"), "\\n"},
483  {std::regex("\\t"), "\\t"},
484  {std::regex("\\r"), "\\r"}
485  };
486 
487 
488  std::string tmp = std::string(desc);
489 
490  for (auto rewrite_rule : rewrite_rules) {
491  tmp = std::regex_replace(tmp, rewrite_rule.first, rewrite_rule.second);
492  }
493 
494  return tmp;
495 }
496 
497 
498 ostream& OutputJSONMachine::print(ostream& stream) {
501 
502  stream << format_head;
503  print_program_info(stream);
504  stream << format_inner;
505 
506  print_base( stream, &root_type_);
507  /*
508  for (Input::TypeRepository<Selection>::TypeRepositoryMapIter it = Input::TypeRepository<Selection>::get_instance().begin();
509  it != Input::TypeRepository<Selection>::get_instance().end(); ++it) {
510  print_base( stream, it->second.get() );
511  }
512  for (Input::TypeRepository<Abstract>::TypeRepositoryMapIter it = Input::TypeRepository<Abstract>::get_instance().begin();
513  it != Input::TypeRepository<Abstract>::get_instance().end(); ++it) {
514  print_base( stream, it->second.get() );
515  }
516  for (Input::TypeRepository<Record>::TypeRepositoryMapIter it = Input::TypeRepository<Record>::get_instance().begin();
517  it != Input::TypeRepository<Record>::get_instance().end(); ++it) {
518  print_base( stream, it->second.get() );
519  }
520 */
521  stream << format_full_hash;
522  print_full_hash(stream);
523  stream << format_tail;
524  return stream;
525 }
526 
527 std::string print_attributes(TypeBase::attribute_map attribute_map) {
528  stringstream stream;
529 
530  if (attribute_map.size() == 0) return "\"attributes\" : {}";
531 
532  stream << "\"attributes\" : {" << endl; // print map of attributes
533  for (auto it=attribute_map.begin(); it!=attribute_map.end(); ++it) {
534  if (it != attribute_map.begin()) {
535  stream << "," << endl;
536  }
537  stream << "\"" << it->first << "\" : " << it->second;
538  }
539  stream << endl << "}";
540 
541  return stream.str();
542 }
543 
544 
545 void OutputJSONMachine::print_type_header(ostream &stream, const TypeBase *type) {
546  stream << "{" << endl;
547  stream << "\"id\" : " << type->hash_str() << "," << endl;
548  stream << "\"input_type\" : \"" + type->class_name() + "\"," << endl;
549  stream << "\"name\" : \"" << type->type_name() << "\"," << endl;
550 
551  // write data of parameters and attributes
552  TypeBase::attribute_map attr_map;
553  TypeBase::TypeHash generic_type_hash;
554  TypeBase::json_string parameter_map_to_json;
555  get_attr_and_param_data(type, attr_map, generic_type_hash, parameter_map_to_json);
556  // print hash of generic type and parameters into separate keys
557  if (generic_type_hash != TypeBase::none_hash) { // print hash of generic type into separate keys
558  stream << "\"generic_type\" : " << TypeBase::hash_str(generic_type_hash) << "," << endl;
559  }
560  if (parameter_map_to_json.size()) { // parameters into separate keys
561  stream << "\"parameters\" : " << parameter_map_to_json << "," << endl;
562  }
563  stream << print_attributes(attr_map);
564 }
565 
566 
567 void OutputJSONMachine::print_impl(ostream& stream, const Record *type) {
568  if (typeid(*type) == typeid(Type::Tuple)) {
569  print_generic<Tuple>(stream, type);
570  } else {
571  print_generic<Record>(stream, type);
572  }
573 
574  TypeBase::TypeHash hash=type->content_hash();
575  if (was_written(hash)) return;
576 
577  print_type_header(stream, type);
578  stream << "," << endl << "\"description\" : \"" <<
579  escape_description( OutputBase::get_record_description(type) ) << "\"," << endl;
580 
581  // parent records, implemented abstracts
583  get_parent_vec(*type, parent_vec);
584  if (parent_vec.size()) {
585  stream << "\"implements\" : [ ";
586  bool add_comma = false;
587  for (auto &parent : parent_vec) {
588  if (add_comma) stream << ", ";
589  else add_comma = true;
590  stream << parent->hash_str();
591  }
592  stream << " ]," << endl;
593  }
594 
595  // reducible to key
596  Record::KeyIter key_it = type->auto_conversion_key_iter();
597  if (key_it != type->end()) {
598  stream << "\"reducible_to_key\" : \"" << key_it->key_ << "\"," << endl;
599  }
600 
601  stream << "\"keys\" : [" << endl;
602 
604  for (Record::KeyIter it = type->begin(); it != type->end(); ++it) {
605  string dft_type, dft_value;
606  get_default(it, dft_type, dft_value);
607  if (dft_type != "value at declaration")
608  dft_value = "\"" + escape_description(dft_value) + "\"";
609 
610  if (it != type->begin()) {
611  stream << "," << endl;
612  }
613  stream << "{ \"key\" : \"" << it->key_ << "\"," << endl;
614  stream << "\"description\" : \"" <<
615  escape_description(it->description_) << "\"," << endl;
616  stream << "\"default\" : { "
617  <<"\"type\" : \"" << dft_type << "\"," << endl
618  <<"\"value\" : " << dft_value << " }," << endl;
619  stream << "\"type\" : " << it->type_->hash_str() << "," << endl;
620  stream << print_attributes(it->attributes);
621  stream << "}";
622  }
623 
624  stream << "]" << endl;
625  stream << "},";
626 
627  // Full documentation of embedded record types.
629  for (Record::KeyIter it = type->begin(); it != type->end(); ++it) {
630  print_base(stream, it->type_.get());
631  }
632 
633  boost::hash_combine(full_hash_, hash);
634 }
635 
636 
637 
638 void OutputJSONMachine::print_impl(ostream& stream, const Array *type) {
639  TypeBase::TypeHash hash=type->content_hash();
640  if (was_written(hash)) return;
641 
642  unsigned int lower_size, upper_size;
643  std::shared_ptr<TypeBase> array_type;
644 
645  get_array_sizes(*type, lower_size, upper_size);
646  get_array_type(*type, array_type);
647 
648  print_type_header(stream, type);
649  stream << "," << endl;
650  stream << "\"range\" : [" << lower_size << ", " << upper_size << "]," << endl;
651  stream << "\"subtype\" : " << array_type->hash_str() << endl;
652  stream << "}," << endl;
653 
654  print_base(stream, array_type.get());
655 
656  boost::hash_combine(full_hash_, hash);
657 }
658 
659 
660 
661 void OutputJSONMachine::print_impl(ostream& stream, const Abstract *type) {
662  print_generic<Abstract>(stream, type);
663 
664  TypeBase::TypeHash hash=type->content_hash();
665  if (was_written(hash)) return;
666 
667  print_type_header(stream, type);
668  stream << "," << endl;
669  stream << "\"description\" : \"" <<
671 
672  print_abstract_record_keys(stream, type);
673  stream << "},";
674 
675  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
676  print_base(stream, &*it);
677  }
678 
679  boost::hash_combine(full_hash_, hash);
680 }
681 
682 
683 void OutputJSONMachine::print_impl(ostream& stream, const AdHocAbstract *type) {
684  print_generic<AdHocAbstract>(stream, type);
685 
686  TypeBase::TypeHash hash=type->content_hash();
687  if (was_written(hash)) return;
688 
689  string parent_name;
690  get_adhoc_parent_name(type, parent_name);
691  print_type_header(stream, type);
692  stream << "," << endl;
693  print_abstract_record_keys(stream, dynamic_cast<const Type::Abstract *>(type));
694  stream << "},";
695 
696  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
697  print_base(stream, &*it);
698  }
699 
700  boost::hash_combine(full_hash_, hash);
701 }
702 
703 
704 
705 void OutputJSONMachine::print_abstract_record_keys(ostream& stream, const Abstract *type) {
706 
707  // Print documentation of abstract record
708  const Record * desc = type->get_default_descendant();
709 
710  // default descendant
711  if (desc) {
712  stream << "\"default_descendant\" : " << desc->hash_str() << "," << endl;
713  }
714  stream << "\"implementations\" : [" << endl;
715  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
716  if (it != type->begin_child_data())
717  stream << "," << endl;
718  stream << "" << it->hash_str() << "";
719  }
720  stream << "]";
721 
722 }
723 
724 
725 
726 
727 
728 void OutputJSONMachine::print_impl(ostream& stream, const Selection *type) {
729  print_generic<Selection>(stream, type);
730 
731  TypeBase::TypeHash hash=type->content_hash();
732  if (was_written(hash)) return;
733 
734  print_type_header(stream, type);
735  stream << "," << endl;
736  stream << "\"description\" : \"" <<
738 
739  stream << "\"values\" : [" << endl;
740  for (Selection::keys_const_iterator it = type->begin(); it != type->end(); ++it) {
741  if (it != type->begin()) {
742  stream << "," << endl;
743  }
744  stream << "{ \"name\" : \"" << it->key_ << "\"," << endl;
745  stream << "\"description\" : \"" << escape_description(it->description_) << "\"," << endl;
746  stream << print_attributes(it->attributes_) << endl;
747  stream << "}";
748  }
749 
750  stream << "]" << endl;
751  stream << "},";
752 
753  boost::hash_combine(full_hash_, hash);
754 }
755 
756 
757 void OutputJSONMachine::print_impl(ostream& stream, const Integer *type) {
758  TypeBase::TypeHash hash=type->content_hash();
759  if (was_written(hash)) return;
760 
761  int lower, upper;
762  get_integer_bounds(*type, lower, upper);
763 
764  print_type_header(stream, type);
765  stream << "," << endl;
766  stream << "\"range\" : [" << lower << ", " << upper << "]" << endl;
767  stream << "},";
768 
769  boost::hash_combine(full_hash_, hash);
770 }
771 
772 
773 void OutputJSONMachine::print_impl(ostream& stream, const Double *type) {
774  TypeBase::TypeHash hash=type->content_hash();
775  if (was_written(hash)) return;
776 
777  double lower, upper;
778  get_double_bounds(*type, lower, upper);
779 
780  print_type_header(stream, type);
781  stream << "," << endl;
782  stream << "\"range\" : [" << lower << ", " << upper << "]" << endl;
783  stream << "},";
784 
785  boost::hash_combine(full_hash_, hash);
786 }
787 
788 
789 void OutputJSONMachine::print_impl(ostream& stream, const Bool *type) {
790  TypeBase::TypeHash hash=type->content_hash();
791  if (was_written(hash)) return;
792 
793  print_type_header(stream, type);
794  stream << "},";
795 
796  boost::hash_combine(full_hash_, hash);
797 }
798 
799 
800 void OutputJSONMachine::print_impl(ostream& stream, const String *type) {
801  TypeBase::TypeHash hash=type->content_hash();
802  if (was_written(hash)) return;
803 
804  print_type_header(stream, type);
805  stream << "},";
806 
807  boost::hash_combine(full_hash_, hash);
808 }
809 
810 
811 void OutputJSONMachine::print_impl(ostream& stream, const FileName *type) {
812  TypeBase::TypeHash hash=type->content_hash();
813  if (was_written(hash)) return;
814 
815  print_type_header(stream, type);
816  stream << "," << endl;
817  stream << "\"file_mode\" : \"";
818  switch (type->get_file_type()) {
819  case ::FilePath::input_file:
820  stream << "input\"";
821  break;
822  case ::FilePath::output_file:
823  stream << "output\"";
824  break;
825  }
826 
827  stream << endl << "},";
828 
829  boost::hash_combine(full_hash_, hash);
830 }
831 
832 
833 
834 void OutputJSONMachine::print_impl(ostream& stream, const Parameter *type) {
835  TypeBase::TypeHash hash=type->content_hash();
836  if (was_written(hash)) return;
837 
838  print_type_header(stream, type);
839  stream << endl << "},";
840 
841  boost::hash_combine(full_hash_, hash);
842 }
843 
844 
845 
847  string build_date = string(__DATE__) + ", " + string(__TIME__);
848 
849  stream << "{" << endl;
850  stream << "\"flow123d_commit\" : \"" << rev_num_data_.revision << "\"," << endl;
851  stream << "\"flow123d_version\" : \"" << rev_num_data_.version << "\"," << endl;
852  stream << "\"date\" : \"" << build_date << "\"" << endl;
853  stream << "}";
854 }
855 
856 
857 
858 void OutputJSONMachine::print_full_hash(ostream& stream) {
859  stream << "\"IST_hash\" : " << TypeBase::hash_str( full_hash_ ) << endl;
860 }
861 
862 
863 
864 
865 
866 
867 std::ostream& operator<<(std::ostream& stream, OutputText type_output) {
868  return type_output.print(stream) << endl;
869 }
870 
871 
872 std::ostream& operator<<(std::ostream& stream, OutputJSONMachine type_output) {
873  return type_output.print(stream) << endl;
874 }
875 
876 
877 } // closing namespace Type
878 } // closing namespace Input
#define ASSERT(expr)
Definition: asserts.hh:351
Type * data_
Definition: armor.hh:873
std::shared_ptr< T > find_hash(Type::TypeBase::TypeHash hash)
static TypeRepository & get_instance()
Return singleton instance of class.
Class for declaration of polymorphic Record.
TypeHash content_hash() const override
Implements TypeBase::content_hash.
ChildDataIter begin_child_data() const
Container-like access to the descendants of the Abstract.
virtual string type_name() const override
Implements Type::TypeBase::type_name.
std::vector< Record >::const_iterator ChildDataIter
Public typedef of constant iterator into array of keys.
const Record * get_default_descendant() const
Returns default descendant.
ChildDataIter end_child_data() const
Container-like access to the descendants of the Abstract.
std::shared_ptr< ChildData > child_data_
Actual data of the Abstract.
unsigned int child_size() const
Returns number of descendants in the child_data_.
Class for declaration of polymorphic Record.
TypeHash content_hash() const override
Implements TypeBase::content_hash.
string class_name() const override
Override Type::TypeBase::class_name.
const Abstract & ancestor_
Reference to ancestor Abstract.
Class for declaration of inputs sequences.
Definition: type_base.hh:339
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:249
Class for declaration of the input of type Bool.
Definition: type_base.hh:452
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:417
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:404
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
bool is_optional() const
Returns true if the key is optional.
Definition: type_record.hh:141
bool is_obligatory() const
Returns true if the key is obligatory and thus must be specified on input. No default value is given.
Definition: type_record.hh:137
const string & value() const
Returns stored value. Possibly empty string.
Definition: type_record.hh:145
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:478
double upper_bound_
Maximal value of Integer.
Definition: type_base.hh:569
double lower_bound_
Minimal value of Integer.
Definition: type_base.hh:568
Class for declaration of the input data that are file names.
Definition: type_base.hh:612
::FilePath::FileType get_file_type() const
Returns type of the file input/output.
Definition: type_base.cc:580
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:538
Class for declaration of the integral input data.
Definition: type_base.hh:483
std::int64_t upper_bound_
Maximal value of Integer.
Definition: type_base.hh:522
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:436
std::int64_t lower_bound_
Minimal value of Integer.
Definition: type_base.hh:521
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:65
void print_generic(ostream &stream, const TypeBase *type)
Definition: type_output.cc:128
void get_default(Record::KeyIter it, string &type, string &value)
Gets values of default for given record key.
Definition: type_output.cc:98
const string & get_selection_description(const Selection *sel)
Gets description of the given selection type.
Definition: type_output.cc:113
TypeBase::TypeHash full_hash_
Content hash of full IST, value is used for key IST_hash.
Definition: type_output.hh:189
void get_attr_and_param_data(const TypeBase *type, TypeBase::attribute_map &attr_map, TypeBase::TypeHash &generic_type_hash, TypeBase::json_string &parameter_map_to_json)
Gets data of attributes and parameters of the given type.
Definition: type_output.cc:226
void clear_processed_types()
Clear all data of processed types.
Definition: type_output.cc:213
OutputBase()
Constructor.
Definition: type_output.cc:48
const string & get_abstract_description(const Abstract *a_rec)
Gets description of the given abstract type.
Definition: type_output.cc:86
void get_array_sizes(Array array, unsigned int &lower, unsigned int &upper)
Gets range of array.
Definition: type_output.cc:67
virtual ~OutputBase()
Destructor.
Definition: type_output.cc:44
@ full_record
Printout full documentation.
Definition: type_output.hh:84
@ key_record
Printout only basic data.
Definition: type_output.hh:83
void get_parent_vec(Record rec, std::vector< std::shared_ptr< Abstract > > &parent_vec)
Gets pointer of parent Abstract for given Record.
Definition: type_output.cc:92
void write_description(std::ostream &stream, const string &str, unsigned int padding, unsigned int hash_count=1)
Write out a string with given padding of every new line.
Definition: type_output.cc:196
bool was_written(std::size_t hash)
Returns true if the type was printed out.
Definition: type_output.cc:219
const string & get_record_description(const Record *rec)
Gets description of the given record type.
Definition: type_output.cc:80
Abstract::ChildDataIter get_adhoc_parent_data(const AdHocAbstract *a_rec)
Gets iterator to begin of ancestor_.child_data_ of the given AdHocAbstract type.
Definition: type_output.cc:123
DocumentationType doc_type_
Type of documentation output.
Definition: type_output.hh:182
void get_integer_bounds(Integer integer, int &lower, int &upper)
Gets range of integer.
Definition: type_output.cc:53
void get_double_bounds(Double dbl, double &lower, double &upper)
Gets range of double.
Definition: type_output.cc:60
void get_array_type(Array array, std::shared_ptr< TypeBase > &arr_type)
Gets pointer of inner type for given Array.
Definition: type_output.cc:74
void write_default_value(std::ostream &stream, Default dft)
Write value stored in dft.
Definition: type_output.cc:188
void get_adhoc_parent_name(const AdHocAbstract *a_rec, string &parent_name)
Gets ancestor_.type_name of the given AdHocAbstract type.
Definition: type_output.cc:118
void print_base(ostream &stream, const TypeBase *type)
Perform resolution according to actual type (using typeid) and call particular print_impl method.
Definition: type_output.cc:136
Class for create JSON machine readable documentation.
Definition: type_output.hh:252
std::string escape_description(std::string desc)
Replace slashes, quotes and special chars with escaped format of these chars.
Definition: type_output.cc:475
void print_program_info(ostream &stream)
Print actual version of program.
Definition: type_output.cc:846
void print_impl(ostream &stream, const Record *type)
Implements printout of Record type.
Definition: type_output.cc:567
std::string format_tail
Tail of the format, printed after all recursive prints are finished.
Definition: type_output.hh:320
void print_type_header(ostream &stream, const TypeBase *type)
Print header of a JSON object describing single TypeBase instance.
Definition: type_output.cc:545
std::string format_full_hash
Tail of the format, printed after all recursive prints are finished and before full hash prints.
Definition: type_output.hh:314
Record root_type_
Root type for output.
Definition: type_output.hh:329
void print_abstract_record_keys(ostream &stream, const Abstract *type)
Print all keys of Abstract type or AdHocAbstract type.
Definition: type_output.cc:705
OutputJSONMachine(RevNumData rev_num_data)
Simple constructor.
Definition: type_output.cc:454
std::string format_head
Header of the format, printed before call of version print.
Definition: type_output.hh:302
RevNumData rev_num_data_
Contains version of program and other base data.
Definition: type_output.hh:322
std::string format_inner
Inner part of the format, printed before first call of recursive print.
Definition: type_output.hh:308
void print_full_hash(ostream &stream)
Print full_hash_ key.
Definition: type_output.cc:858
ostream & print(ostream &stream) override
Performs output of the documentation into given stream.
Definition: type_output.cc:498
Class for create text documentation.
Definition: type_output.hh:208
void print_impl(ostream &stream, const Record *type)
Implements printout of Record type.
Definition: type_output.cc:250
ostream & print(ostream &stream) override
Performs output of the documentation into given stream.
Definition: type_output.cc:242
Class for representing parametric types in IST.
Definition: type_generic.hh:53
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_generic.cc:54
Record type proxy class.
Definition: type_record.hh:182
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:602
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_record.cc:317
virtual TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_record.cc:123
FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_) override
Finish declaration of the Record type.
Definition: type_record.cc:243
bool is_finished() const override
Implements TypeBase::is_finished.
Definition: type_record.cc:231
std::shared_ptr< RecordData > data_
Data handle.
Definition: type_record.hh:531
virtual string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_record.cc:323
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:579
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:216
KeyIter end() const
Container-like access to the keys of the Record.
Definition: type_record.hh:587
KeyIter auto_conversion_key_iter() const
Returns iterator to auto-conversion key.
Definition: type_record.cc:335
Template for classes storing finite set of named values.
unsigned int size() const
Returns number of values in the Selection.
keys_const_iterator end() const
Container-like access to the keys of the Selection.
bool is_finished() const override
Implements TypeBase::is_finished.
TypeHash content_hash() const override
Implements TypeBase::content_hash.
std::shared_ptr< SelectionData > data_
Handle to actual Selection data.
string type_name() const override
Implements Type::TypeBase::type_name.
std::vector< struct Key >::const_iterator keys_const_iterator
Public typedef of constant iterator into array of keys.
keys_const_iterator begin() const
Container-like access to the keys of the Selection.
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:599
string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_base.cc:614
Tuple type proxy class.
Definition: type_tuple.hh:45
Base of classes for declaring structure of the input data.
Definition: type_base.hh:92
std::string json_string
String stored in JSON format.
Definition: type_base.hh:99
virtual string type_name() const
Returns an identification of the type. Useful for error messages.
Definition: type_base.cc:206
TypeHash generic_type_hash_
hash string of generic type if type is derived, or empty string
Definition: type_base.hh:304
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:95
virtual string class_name() const
Returns an identification of the class. Useful for output of the documentation.
Definition: type_base.cc:211
json_string print_parameter_map_to_json(ParameterMap parameter_map) const
Create JSON output from parameter_map formatted as value of attribute.
Definition: type_base.cc:151
std::shared_ptr< attribute_map > attributes_
map of type attributes (e. g. input_type, name etc.)
Definition: type_base.hh:298
ParameterMap parameter_map_
map of parameters if type is part of generic subtree
Definition: type_base.hh:307
std::string hash_str() const
Format the hash of this type.
Definition: type_base.hh:220
static std::string hash_str(TypeHash hash)
Format given hash for output.
Definition: type_base.cc:125
static const TypeHash none_hash
Definition: type_base.hh:96
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
static constexpr bool value
Definition: json.hpp:87
Array< double > array
Definition: armor.hh:890
std::ostream & operator<<(std::ostream &stream, const TypeBase &type)
For convenience we provide also redirection operator for output documentation of Input:Type classes.
Definition: type_base.cc:239
std::string print_attributes(TypeBase::attribute_map attribute_map)
Definition: type_output.cc:527
Abstract linear system class.
Definition: balance.hh:40
#define FMT_UNUSED
Definition: posix.h:75
Stores version of program and other base data of application.
Definition: type_output.hh:44
std::string revision
Actual revision of application.
Definition: type_output.hh:46
std::string version
Actual version of application.
Definition: type_output.hh:45