https://mooseframework.inl.gov
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
SONDefinitionFormatter Class Reference

This class produces a dump of the InputFileParameters in the Standard Object Notation (SON) format for use by the Hierarchical Input Validation Engine (HIVE) in the NEAMS Workbench. More...

#include <SONDefinitionFormatter.h>

Public Member Functions

 SONDefinitionFormatter ()
 
std::string toString (const nlohmann::json &root)
 returns a string representation of the tree in input file format More...
 

Protected Member Functions

void addLine (const std::string &line)
 adds a line to the output with the proper indentation automatically More...
 
void addBlock (const std::string &block_name, const nlohmann::json &block, bool is_typeblock=false, const std::string &parent_name="", const nlohmann::json &parameters_in=nlohmann::json(nullptr), const nlohmann::json &subblocks_in=nlohmann::json(nullptr))
 adds a new block to the output More...
 
void addParameters (const nlohmann::json &params)
 adds all parameters from a given block More...
 

Protected Attributes

const int _spaces
 
int _level
 
std::ostringstream _stream
 
std::map< std::string, std::vector< std::string > > _assoc_types_map
 
nlohmann::json _global_params
 

Detailed Description

This class produces a dump of the InputFileParameters in the Standard Object Notation (SON) format for use by the Hierarchical Input Validation Engine (HIVE) in the NEAMS Workbench.

It takes its input from JsonSyntaxTree.

Definition at line 22 of file SONDefinitionFormatter.h.

Constructor & Destructor Documentation

◆ SONDefinitionFormatter()

SONDefinitionFormatter::SONDefinitionFormatter ( )

Member Function Documentation

◆ addBlock()

void SONDefinitionFormatter::addBlock ( const std::string &  block_name,
const nlohmann::json &  block,
bool  is_typeblock = false,
const std::string &  parent_name = "",
const nlohmann::json &  parameters_in = nlohmann::json(nullptr),
const nlohmann::json &  subblocks_in = nlohmann::json(nullptr) 
)
protected

adds a new block to the output

Parameters
block_name- name of the block
block- json holding data for the block
parameters_in- if a typeblock, the parameters for inheritance
subblocks_in- if a typeblock, the subblocks for inheritance
is_typeblock- true only if block being added is a typeblock

Definition at line 68 of file SONDefinitionFormatter.C.

Referenced by toString().

74 {
75  // open block with "_type" appended to the name if this is a TypeBlock because the
76  // parser appends "_type" to the name of blocks with a "type=" parameter specified
77  addLine("'" + block_name + (is_typeblock ? "_type" : "") + "'{");
78  _level++;
79 
80  // decide the actual block [./declarator] name that will be specified later unless
81  // this is a StarBlock and then decide if this is a StarBlock or not for later use
82  // - if TypeBlock : this will be the parent block name
83  // - if NormalBlock : this will be this block name
84  std::string block_decl = (is_typeblock ? parent_name : block_name);
85  bool is_starblock = (block_decl == "*" ? true : false);
86 
87  // - add InputTmpl : the autocomplete template that is used for all block types
88  // - add InputName : if is_typeblock then this will be dropped in after "type="
89  // - add InputType : block type - normal_top / normal_sub / type_top / type_sub
90  // - add InputDefault : block [./declarator] name from above that will be used for
91  // autocompletion of this block unless it is a StarBlock then
92  // [./insert_name_here] will be used because any name is okay
93  addLine("InputTmpl=MooseBlock");
94  addLine("InputName=\"" + block_name + "\"");
95  if (!is_typeblock)
96  addLine(_level == 1 ? "InputType=normal_top" : "InputType=normal_sub");
97  else
98  addLine(_level == 1 ? "InputType=type_top" : "InputType=type_sub");
99  if (!is_starblock)
100  addLine("InputDefault=\"" + block_decl + "\"");
101  else
102  addLine("InputDefault=\"insert_name_here\"");
103 
104  // add Description of block if it exists
105  std::string description = block.contains("description") ? block["description"] : "";
106  pcrecpp::RE("\"").GlobalReplace("'", &description);
107  pcrecpp::RE("[\r\n]").GlobalReplace(" ", &description);
108  if (!description.empty())
109  addLine("Description=\"" + description + "\"");
110 
111  // ensure every block has no more than one string declarator node and if this is a
112  // TypeBlock but not a StarBlock then also ensure that the block [./declarator] is
113  // the expected block_decl from above which should be the name of the parent block
114  addLine("decl{");
115  _level++;
116  addLine("MaxOccurs=1");
117  if (is_typeblock && !is_starblock)
118  addLine("ValEnums=[ \"" + block_decl + "\" ]");
119  _level--;
120  addLine("}");
121 
122  // if this block is the GlobalParams block then add a add "*/value" level
123  if (block_name == "GlobalParams")
124  {
125  addLine("'*'{");
126  _level++;
127  addLine("'value'{");
128  addLine("}");
129  _level--;
130  addLine("}");
131  }
132 
133  // store parameters ---
134  // first : start with global parameters as a base
135  // second : add or overwrite with any parameter inheritance
136  // third : add or overwrite with any local RegularParameters
137  // fourth : add or overwrite with any local ActionParameters
138  nlohmann::json parameters = _global_params;
139  for (const auto & el : parameters_in.items())
140  parameters[el.key()] = el.value();
141  if (block.contains("parameters"))
142  {
143  for (const auto & el : block["parameters"].items())
144  parameters[el.key()] = el.value();
145  }
146 
147  if (block.contains("actions"))
148  {
149  for (const auto & el : block["actions"].items())
150  if (el.value().contains("parameters"))
151  for (const auto & param_el : el.value()["parameters"].items())
152  parameters[param_el.key()] = param_el.value();
153  }
154 
155  // store NormalBlock children ---
156  // first : start with any NormalBlock inheritance passed in as a base
157  // second : add or overwrite these with any local NormalBlock children
158  // third : add star named child block if it exists
159  nlohmann::json subblocks = subblocks_in;
160  if (block.contains("subblocks"))
161  {
162  for (const auto & el : block["subblocks"].items())
163  subblocks[el.key()] = el.value();
164  }
165  if (block.contains("star"))
166  subblocks["*"] = block["star"];
167 
168  // store TypeBlock children ---
169  // first : start with ["types"] child block as a base
170  // second : add ["subblock_types"] child block
171  nlohmann::json typeblocks = block.contains("types") ? block["types"] : nlohmann::json();
172  if (block.contains("subblock_types"))
173  for (const auto & el : block["subblock_types"].items())
174  typeblocks[el.key()] = el.value();
175 
176  // add parameters ---
177  // if this block has a "type=" parameter with a specified default "type=" name and
178  // if that default is also the name of a saved TypeBlock child then the parameters
179  // belonging to that default saved TypeBlock child are added to this block as well
180  // first : start with default saved TypeBlock child's RegularParameters as a base
181  // second : add or overwrite with default saved TypeBlock child's ActionParameters
182  // third : add or overwrite with parameters that were stored above for this block
183  // fourth : either add newly stored parameters or add previously stored parameters
184  if (parameters.contains("type") && parameters["type"].contains("default") &&
185  parameters["type"]["default"].is_string() &&
186  typeblocks.contains(parameters["type"]["default"].get<std::string>()))
187  {
188  std::string type_default = parameters["type"]["default"].get<std::string>();
189  const nlohmann::json & default_block = typeblocks[type_default];
190  if (default_block.contains("parameters"))
191  {
192  nlohmann::json default_child_params = default_block["parameters"];
193  if (default_block.contains("actions"))
194  {
195  const nlohmann::json & default_actions = default_block["actions"];
196  for (const auto & el : default_actions.items())
197  {
198  if (el.value().contains("parameters"))
199  for (const auto & param_el : el.value()["parameters"].items())
200  default_child_params[param_el.key()] = param_el.value();
201  }
202  }
203 
204  // unrequire the 'file' parameter added to the Mesh via the FileMesh TypeBlock
205  // since MeshGenerators internally change the default block type from FileMesh
206  if (block_name == "Mesh" && default_child_params.contains("file") &&
207  default_child_params["file"].contains("required") &&
208  default_child_params["file"]["required"].is_boolean())
209  default_child_params["file"]["required"] = false;
210 
211  for (const auto & el : parameters.items())
212  default_child_params[el.key()] = el.value();
213  addParameters(default_child_params);
214  }
215  }
216  else
217  addParameters(parameters);
218 
219  // add previously stored NormalBlocks children recursively
220  for (const auto & el : subblocks.items())
221  addBlock(el.key(), el.value());
222 
223  // close block now because the parser stores TypeBlock children at this same level
224  _level--;
225  addLine("} % end block " + block_name + (is_typeblock ? "_type" : ""));
226 
227  // add all previously stored TypeBlock children recursively and pass the parameter
228  // and NormalBlock children added at this level in as inheritance to all TypeBlock
229  // children so that they may each also add them and pass in the name of this block
230  // as well so that all TypeBlock children can add a rule ensuring that their block
231  // [./declarator] is the name of this parent block unless this block is named star
232  for (const auto & el : typeblocks.items())
233  addBlock(el.key(), el.value(), true, block_name, parameters, subblocks);
234 }
void addParameters(const nlohmann::json &params)
adds all parameters from a given block
void addLine(const std::string &line)
adds a line to the output with the proper indentation automatically
void addBlock(const std::string &block_name, const nlohmann::json &block, bool is_typeblock=false, const std::string &parent_name="", const nlohmann::json &parameters_in=nlohmann::json(nullptr), const nlohmann::json &subblocks_in=nlohmann::json(nullptr))
adds a new block to the output

◆ addLine()

void SONDefinitionFormatter::addLine ( const std::string &  line)
protected

adds a line to the output with the proper indentation automatically

Parameters
line- the line to add

Definition at line 58 of file SONDefinitionFormatter.C.

Referenced by addBlock(), and addParameters().

59 {
60  _stream << line << "\n";
61  return;
62 }

◆ addParameters()

void SONDefinitionFormatter::addParameters ( const nlohmann::json &  params)
protected

adds all parameters from a given block

Parameters
params- json holding data for all of the given block's parameters

Definition at line 255 of file SONDefinitionFormatter.C.

Referenced by addBlock().

256 {
257 
258  // build list of any '_object_params_set_by_action' that are not required in input
259  std::vector<std::string> action_set_params;
260  if (params.contains("_object_params_set_by_action") &&
261  params["_object_params_set_by_action"].contains("default"))
262  {
263  std::string opsba = nlohmann::to_string(params["_object_params_set_by_action"]["default"]);
264  if (opsba.front() == '"' && opsba.back() == '"')
265  {
266  opsba.erase(opsba.begin());
267  opsba.pop_back();
268  }
269  action_set_params = MooseUtils::split(MooseUtils::trim(opsba), " ");
270  }
271 
272  for (const auto & el : params.items())
273  {
274  auto & name = el.key();
275  auto & param = el.value();
276 
277  // skip '_object_params_set_by_action' parameters because they will not be input
278  if (name == "_object_params_set_by_action")
279  continue;
280 
281  // lambda to calculate relative path from the current level to the document root
282  auto backtrack = [](int level)
283  {
284  std::string backtrack_path;
285  for (int i = 0; i < level; ++i)
286  backtrack_path += "../";
287  return backtrack_path;
288  };
289 
290  // capture the cpp_type and basic_type and strip off any unnecessary information
291  std::string cpp_type = param["cpp_type"];
292  std::string basic_type = param["basic_type"];
293  bool is_array = false;
294  if (cpp_type == "FunctionExpression" || cpp_type == "FunctionName" ||
295  basic_type.compare(0, 6, "Array:") == 0 || cpp_type.compare(0, 13, "Eigen::Matrix") == 0)
296  is_array = true;
297  pcrecpp::RE(".+<([A-Za-z0-9_' ':]*)>.*").GlobalReplace("\\1", &cpp_type);
298  pcrecpp::RE("(Array:)*(.*)").GlobalReplace("\\2", &basic_type);
299 
300  // *** ChildAtLeastOne of parameter
301  // if parameter is required, not action set, and no default exists, then specify
302  // ChildAtLeastOne = [ "backtrack/GlobalParams/name/value" "name/value" ]
303  auto def_ptr = param.find("default");
304  std::string def;
305  if (def_ptr != param.end())
306  def = def_ptr->is_string() ? def_ptr->get<std::string>() : nlohmann::to_string(*def_ptr);
307  def = MooseUtils::trim(def);
308  if (param.contains("required") &&
309  std::find(action_set_params.begin(), action_set_params.end(), name) ==
310  action_set_params.end())
311  {
312  bool required = param["required"];
313  if (required && def.empty())
314  addLine("ChildAtLeastOne=[ \"" + backtrack(_level) + "GlobalParams/" + name +
315  "/value\" \"" + name + "\" ]");
316  }
317 
318  // *** open parameter
319  addLine("'" + name + "'" + "{");
320  _level++;
321 
322  // *** InputTmpl of parameter
323  addLine("InputTmpl=MooseParam");
324 
325  // *** InputType of parameter
326  if (is_array)
327  addLine("InputType=key_array");
328  else
329  addLine("InputType=key_value");
330 
331  // *** InputName of parameter
332  addLine("InputName=\"" + name + "\"");
333 
334  // *** Description of parameter
335  if (param.contains("description"))
336  {
337  std::string description = param["description"];
338  pcrecpp::RE("\"").GlobalReplace("'", &description);
339  pcrecpp::RE("[\r\n]").GlobalReplace(" ", &description);
340  if (!description.empty())
341  addLine("Description=\"" + description + "\"");
342  }
343 
344  // *** MaxOccurs=1 for each parameter
345  addLine("MaxOccurs=1");
346 
347  // *** open parameter's value
348  addLine("'value'{");
349  _level++;
350 
351  // *** MinOccurs / MaxOccurs of parameter's value
352  // is_array indicates the parameter value child may occur zero or multiple times
353  if (!is_array)
354  {
355  addLine("MinOccurs=1");
356  addLine("MaxOccurs=1");
357  }
358 
359  // *** ValType of parameter's value
360  if (basic_type == "Integer")
361  addLine("ValType=Int");
362  else if (basic_type == "Real")
363  addLine("ValType=Real");
364 
365  // *** ValEnums / InputChoices of parameter's value
366  if (basic_type.find("Boolean") != std::string::npos)
367  addLine("ValEnums=[ true false 1 0 on off ]");
368  else
369  {
370  std::string options = param["options"];
371  if (!options.empty())
372  {
373  pcrecpp::RE(" ").GlobalReplace("\" \"", &options);
374  if (!param["out_of_range_allowed"])
375  addLine("ValEnums=[ \"" + options + "\" ]");
376  else
377  addLine("InputChoices=[ \"" + options + "\" ]");
378  }
379  }
380 
381  // *** InputChoices (lookups) of parameter's value
382  // add any reserved_values then check if there are any paths associated with the
383  // cpp_type in the assoc_types_map that was built before traversal and add those
384  // paths relative to this node here as well
385  std::string choices;
386  if (param.contains("reserved_values"))
387  {
388  for (const auto & reserved : param["reserved_values"])
389  choices += nlohmann::to_string(reserved) + " ";
390  }
391 
392  for (const auto & path : _assoc_types_map[cpp_type])
393  choices += "PATH:\"" + backtrack(_level) + path + "/decl\" ";
394  if (!choices.empty())
395  addLine("InputChoices=[ " + choices + "]");
396 
397  // *** MinValInc of parameter's value
398  if (cpp_type.compare(0, 8, "unsigned") == 0 && basic_type == "Integer")
399  addLine("MinValInc=0");
400 
401  // *** InputDefault of parameter's value
402  if (!def.empty())
403  addLine("InputDefault=\"" + def + "\"");
404 
405  // *** close parameter's value
406  _level--;
407  addLine("}");
408 
409  // *** close parameter
410  _level--;
411  addLine("}");
412  }
413 }
std::string name(const ElemQuality q)
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Python like split functions for strings.
Definition: MooseUtils.C:1126
std::map< std::string, std::vector< std::string > > _assoc_types_map
std::string trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
void addLine(const std::string &line)
adds a line to the output with the proper indentation automatically

◆ toString()

std::string SONDefinitionFormatter::toString ( const nlohmann::json &  root)

returns a string representation of the tree in input file format

Parameters
root- the root node of the tree to output

Definition at line 24 of file SONDefinitionFormatter.C.

Referenced by MooseApp::setupOptions().

25 {
26 
27  const std::map<std::string, std::string> json_path_regex_replacement_map = {
28  {"/star/subblock_types/([A-Za-z0-9_]*)/", "/\\1_type/"},
29  {"[A-Za-z0-9_]*/types/([A-Za-z0-9_]*)/", "\\1_type/"},
30  {"/actions/[A-Za-z0-9_]*/parameters/", "/"},
31  {"/parameters/", "/"},
32  {"/subblocks/", "/"}};
33 
34  for (const auto & el : root["global"]["associated_types"].items())
35  {
36  const auto & type = el.key();
37  for (const auto & el_path : el.value().items())
38  {
39  std::string path = el_path.value();
40  for (const auto & map_iter : json_path_regex_replacement_map)
41  pcrecpp::RE(map_iter.first).GlobalReplace(map_iter.second, &path);
42  _assoc_types_map[type].push_back(path);
43  }
44  }
45 
46  _global_params = root["global"]["parameters"];
47  _stream.clear();
48  _stream.str("");
49  for (const auto & el : root["blocks"].items())
50  addBlock(el.key(), el.value());
51  return _stream.str();
52 }
std::map< std::string, std::vector< std::string > > _assoc_types_map
void addBlock(const std::string &block_name, const nlohmann::json &block, bool is_typeblock=false, const std::string &parent_name="", const nlohmann::json &parameters_in=nlohmann::json(nullptr), const nlohmann::json &subblocks_in=nlohmann::json(nullptr))
adds a new block to the output

Member Data Documentation

◆ _assoc_types_map

std::map<std::string, std::vector<std::string> > SONDefinitionFormatter::_assoc_types_map
protected

Definition at line 65 of file SONDefinitionFormatter.h.

Referenced by addParameters(), and toString().

◆ _global_params

nlohmann::json SONDefinitionFormatter::_global_params
protected

Definition at line 66 of file SONDefinitionFormatter.h.

Referenced by addBlock(), and toString().

◆ _level

int SONDefinitionFormatter::_level
protected

Definition at line 63 of file SONDefinitionFormatter.h.

Referenced by addBlock(), and addParameters().

◆ _spaces

const int SONDefinitionFormatter::_spaces
protected

Definition at line 62 of file SONDefinitionFormatter.h.

◆ _stream

std::ostringstream SONDefinitionFormatter::_stream
protected

Definition at line 64 of file SONDefinitionFormatter.h.

Referenced by addLine(), and toString().


The documentation for this class was generated from the following files: