Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "YAMLFormatter.h" 11 : 12 : // MOOSE includes 13 : #include "MooseEnum.h" 14 : #include "MultiMooseEnum.h" 15 : #include "Parser.h" 16 : 17 : #include "libmesh/vector_value.h" 18 : #include "libmesh/point.h" 19 : 20 : // C++ includes 21 : #include <sstream> 22 : #include <vector> 23 : 24 18 : YAMLFormatter::YAMLFormatter(bool dump_mode) : SyntaxTree(true), _dump_mode(dump_mode) {} 25 : 26 : std::string 27 18 : YAMLFormatter::preamble() const 28 : { 29 : // important: start and end yaml data delimiters used by python 30 36 : return "**START YAML DATA**\n"; 31 : } 32 : 33 : std::string 34 18 : YAMLFormatter::postscript() const 35 : { 36 36 : return "**END YAML DATA**\n"; 37 : } 38 : 39 : std::string 40 50400 : YAMLFormatter::printParams(const std::string & prefix, 41 : const std::string & /*fully_qualified_name*/, 42 : InputParameters & params, 43 : short depth, 44 : const std::string & search_string, 45 : bool & found) 46 : { 47 50400 : std::ostringstream oss; 48 50400 : std::string indent(depth * 2, ' '); 49 : 50 1734036 : for (auto & iter : params) 51 : { 52 1683636 : std::string name = iter.first; 53 : // First make sure we want to see this parameter, also block active and type 54 2565420 : if (params.isPrivate(iter.first) || name == "active" || 55 2565420 : (search_string != "" && search_string != iter.first) || haveSeenIt(prefix, iter.first)) 56 1230795 : continue; 57 : 58 452841 : found = true; 59 : 60 : // Mark it as "seen" 61 452841 : seenIt(prefix, iter.first); 62 : 63 : // Block params may be required and will have a doc string 64 452841 : std::string required = params.isParamRequired(iter.first) ? "Yes" : "No"; 65 : 66 452841 : oss << indent << " - name: " << name << "\n"; 67 452841 : oss << indent << " required: " << required << "\n"; 68 452841 : oss << indent << " default: !!str "; 69 : 70 : // Only output default if it has one 71 452841 : if (params.isParamValid(iter.first)) 72 : { 73 : // prints the value, which is the default value when dumping the tree 74 : // because it hasn't been changed 75 : 76 : // Output stream, performing special operations for writing objects such as Points and 77 : // RealVectorValues 78 305472 : std::ostringstream toss; 79 305472 : buildOutputString(toss, iter); 80 : 81 : // remove additional '\n' possibly generated in output (breaks YAML parsing) 82 305472 : std::string tmp_str = toss.str(); 83 1673445 : for (auto & ch : tmp_str) 84 1367973 : if (ch == '\n') 85 0 : ch = ' '; 86 305472 : if (tmp_str == ",") 87 63 : oss << "\"" << tmp_str << "\""; 88 : else 89 305409 : oss << tmp_str; 90 305472 : } 91 147369 : else if (params.hasDefaultCoupledValue(iter.first)) 92 372 : oss << params.defaultCoupledValue(iter.first); 93 : 94 452841 : std::string doc = params.getDocString(iter.first); 95 452841 : MooseUtils::escape(doc); 96 : // Print the type 97 : oss << "\n" 98 452841 : << indent << " cpp_type: " << params.type(iter.first) << "\n" 99 452841 : << indent << " group_name: "; 100 452841 : std::string group_name = params.getGroupName(iter.first); 101 452841 : if (!group_name.empty()) 102 282141 : oss << "'" << group_name << "'"; 103 452841 : oss << "\n"; 104 : 105 452841 : oss << indent << " doc_unit: "; 106 452841 : std::string doc_unit = params.getDocUnit(iter.first); 107 452841 : if (!doc_unit.empty()) 108 252 : oss << "'" << doc_unit << "'"; 109 452841 : oss << "\n"; 110 : 111 452841 : oss << indent << " doc_range: "; 112 452841 : std::string doc_range; 113 452841 : if (params.isRangeChecked(iter.first)) 114 7050 : doc_range = params.rangeCheckedFunction(iter.first); 115 452841 : if (!doc_range.empty()) 116 7050 : oss << "'" << doc_range << "'"; 117 452841 : oss << "\n"; 118 : 119 452841 : if (params.have_parameter<MooseEnum>(name)) 120 22839 : addEnumOptionsAndDocs(oss, params.get<MooseEnum>(name), indent); 121 452841 : if (params.have_parameter<MultiMooseEnum>(name)) 122 15681 : addEnumOptionsAndDocs(oss, params.get<MultiMooseEnum>(name), indent); 123 452841 : if (params.have_parameter<ExecFlagEnum>(name)) 124 10227 : addEnumOptionsAndDocs(oss, params.get<ExecFlagEnum>(name), indent); 125 452841 : if (params.have_parameter<std::vector<MooseEnum>>(name)) 126 72 : addEnumOptionsAndDocs(oss, params.get<std::vector<MooseEnum>>(name)[0], indent); 127 : 128 452841 : oss << indent << " description: |\n " << indent << doc << std::endl; 129 1683636 : } 130 : 131 100800 : return oss.str(); 132 50400 : } 133 : 134 : template <typename T> 135 : void 136 48819 : YAMLFormatter::addEnumOptionsAndDocs(std::ostringstream & oss, 137 : T & param, 138 : const std::string & indent) 139 : { 140 48819 : oss << indent << " options: " << param.getRawNames() << '\n'; 141 48819 : const auto & docs = param.getItemDocumentation(); 142 48819 : if (!docs.empty()) 143 : { 144 117 : oss << indent << " option_docs:\n"; 145 441 : for (const auto & doc : docs) 146 : { 147 324 : oss << indent << " - name: " << doc.first.name() << "\n"; 148 324 : oss << indent << " description: |\n"; 149 324 : oss << indent << " " << doc.second << "\n"; 150 : } 151 : } 152 48819 : } 153 : 154 : std::string 155 51492 : YAMLFormatter::preTraverse(short depth) const 156 : { 157 51492 : std::string indent(depth * 2, ' '); 158 : 159 102984 : return indent + " subblocks:\n"; 160 51492 : } 161 : 162 : std::string 163 51492 : YAMLFormatter::printBlockOpen(const std::string & name, short depth, const std::string & doc) 164 : { 165 51492 : std::ostringstream oss; 166 51492 : std::string indent(depth * 2, ' '); 167 : 168 51492 : std::string docEscaped = doc; 169 51492 : MooseUtils::escape(docEscaped); 170 : 171 51492 : oss << indent << "- name: " << name << "\n"; 172 51492 : oss << indent << " description: |\n" << indent << " " << docEscaped << "\n"; 173 51492 : oss << indent << " parameters:\n"; 174 : 175 102984 : return oss.str(); 176 51492 : } 177 : 178 : std::string 179 51492 : YAMLFormatter::printBlockClose(const std::string & /*name*/, short /*depth*/) const 180 : { 181 51492 : return std::string(); 182 : } 183 : 184 : void 185 305472 : YAMLFormatter::buildOutputString( 186 : std::ostringstream & output, 187 : const std::iterator_traits<InputParameters::iterator>::value_type & p) 188 : { 189 305472 : libMesh::Parameters::Value * val = MooseUtils::get(p.second); 190 : 191 : // Account for Point 192 305472 : InputParameters::Parameter<Point> * ptr0 = dynamic_cast<InputParameters::Parameter<Point> *>(val); 193 : 194 : // Account for RealVectorValues 195 : InputParameters::Parameter<RealVectorValue> * ptr1 = 196 305472 : dynamic_cast<InputParameters::Parameter<RealVectorValue> *>(val); 197 : 198 : // Output the Point components 199 305472 : if (ptr0) 200 306 : output << ptr0->get().operator()(0) << " " << ptr0->get().operator()(1) << " " 201 306 : << ptr0->get().operator()(2); 202 : 203 : // Output the RealVectorValue components 204 305166 : else if (ptr1) 205 204 : output << ptr1->get().operator()(0) << " " << ptr1->get().operator()(1) << " " 206 204 : << ptr1->get().operator()(2); 207 : 208 : // General case, call the print operator 209 : else 210 304962 : p.second->print(output); 211 305472 : }