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