https://mooseframework.inl.gov
Builder.C
Go to the documentation of this file.
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 "MooseUtils.h"
11 #include "InputParameters.h"
12 #include "ActionFactory.h"
13 #include "Action.h"
14 #include "Factory.h"
15 #include "Parser.h"
16 #include "MooseObjectAction.h"
18 #include "ActionWarehouse.h"
19 #include "EmptyAction.h"
20 #include "MooseApp.h"
21 #include "GlobalParamsAction.h"
22 #include "SyntaxTree.h"
23 #include "InputFileFormatter.h"
24 #include "YAMLFormatter.h"
25 #include "MooseTypes.h"
26 #include "CommandLine.h"
27 #include "JsonSyntaxTree.h"
28 #include "Syntax.h"
29 #include "ParameterRegistry.h"
30 
31 #include "libmesh/parallel.h"
32 #include "libmesh/fparser.hh"
33 
34 #include <string>
35 #include <fstream>
36 #include <iomanip>
37 #include <algorithm>
38 #include <cstdlib>
39 #include <filesystem>
40 
41 namespace Moose
42 {
43 
44 bool
45 isSectionActive(const hit::Node & node)
46 {
47  const hit::Node * n = &node;
48  while (n)
49  {
50  const auto section = n->parent();
51  if (section)
52  {
53  // only check current level, not nested ones
54  if (const auto active = section->find("active");
55  active && active->type() == hit::NodeType::Field && active->parent() == section)
56  {
57  const auto vars = active->param<std::vector<std::string>>();
58  return std::find_if(vars.begin(),
59  vars.end(),
60  [&n](const auto & var)
61  { return n->path() == hit::pathNorm(var); }) != vars.end();
62  }
63  // only check current level, not nested ones
64  if (const auto inactive = section->find("inactive");
65  inactive && inactive->type() == hit::NodeType::Field && inactive->parent() == section)
66  {
67  const auto vars = inactive->param<std::vector<std::string>>();
68  return std::find_if(vars.begin(),
69  vars.end(),
70  [&n](const auto & var)
71  { return n->path() == hit::pathNorm(var); }) == vars.end();
72  }
73  }
74  n = section;
75  }
76  return true;
77 }
78 
79 std::vector<std::string>
80 findSimilar(const std::string & param, const std::vector<std::string> & options)
81 {
82  std::vector<std::string> candidates;
83  if (options.size() == 0)
84  return candidates;
85 
86  int mindist = MooseUtils::levenshteinDist(options[0], param);
87  for (const auto & opt : options)
88  {
89  const int dist = MooseUtils::levenshteinDist(opt, param);
90  // magic number heuristics to get similarity distance cutoff
91  const int dist_cutoff = 1 + param.size() / 5;
92  if (dist > dist_cutoff || dist > mindist)
93  continue;
94 
95  if (dist < mindist)
96  {
97  mindist = dist;
98  candidates.clear();
99  }
100  candidates.push_back(opt);
101  }
102  return candidates;
103 }
104 
105 Builder::Builder(MooseApp & app, ActionWarehouse & action_wh, Parser & parser)
106  : ConsoleStreamInterface(app),
107  _app(app),
108  _factory(app.getFactory()),
109  _action_wh(action_wh),
110  _action_factory(app.getActionFactory()),
111  _syntax(_action_wh.syntax()),
112  _parser(parser),
113  _root(_parser.getRoot()),
114  _syntax_formatter(nullptr)
115 {
116 }
117 
119 
122 {
124 
129  params.addParam<std::vector<std::string>>(
130  "active",
131  std::vector<std::string>({"__all__"}),
132  "If specified only the blocks named will be visited and made active");
133  params.addParam<std::vector<std::string>>(
134  "inactive",
135  std::vector<std::string>(),
136  "If specified blocks matching these identifiers will be skipped.");
137 
138  return params;
139 }
140 
141 std::vector<std::string>
142 Builder::listValidParams(std::string & section_name)
143 {
144  bool dummy;
145  std::string registered_identifier = _syntax.isAssociated(section_name, &dummy);
146  auto iters = _syntax.getActions(registered_identifier);
147 
148  std::vector<std::string> paramlist;
149  for (auto it = iters.first; it != iters.second; ++it)
150  {
151  auto params = _action_factory.getValidParams(it->second._action);
152  for (const auto & it : params)
153  paramlist.push_back(it.first);
154  }
155  return paramlist;
156 }
157 
158 void
159 UnusedWalker::walk(const std::string & fullpath, const std::string & nodename, hit::Node * n)
160 {
161  // the line() > 0 check allows us to skip nodes that were merged into this tree (i.e. CLI
162  // args) because their unused params are checked+reported independently of the ones in the
163  // main tree.
164  if (!_used.count(fullpath) && nodename != "active" && nodename != "inactive" &&
165  isSectionActive(*n) && n->line() > 0)
166  {
167  auto section_name = fullpath.substr(0, fullpath.rfind("/"));
168  const auto paramlist = _builder.listValidParams(section_name);
169  const auto candidates = findSimilar(nodename, paramlist);
170  if (candidates.size() > 0)
171  errors.emplace_back(
172  "unused parameter '" + fullpath + "'; did you mean '" + candidates[0] + "'?", n);
173  else
174  errors.emplace_back("unused parameter '" + fullpath + "'", n);
175  }
176 }
177 
178 std::string
179 Builder::getPrimaryFileName(bool strip_leading_path) const
180 {
181  const auto path = _parser.getLastInputFilePath();
182  return (strip_leading_path ? path.filename() : std::filesystem::absolute(path)).string();
183 }
184 
185 void
186 Builder::walkRaw(std::string /*fullpath*/, std::string /*nodepath*/, hit::Node * n)
187 {
188  InputParameters active_list_params = Action::validParams();
190 
191  const std::string section_name = n->fullpath();
192  const std::string curr_identifier = n->fullpath();
193 
194  // Before we retrieve any actions or build any objects, make sure that the section they are in
195  // is active
196  if (!isSectionActive(*n))
197  return;
198 
199  // Extract the block parameters before constructing the action
200  // There may be more than one Action registered for a given section in which case we need to
201  // build them all
202  bool is_parent;
203  std::string registered_identifier = _syntax.isAssociated(section_name, &is_parent);
204 
205  // Make sure at least one action is associated with the current identifier
206  if (const auto [begin, end] = _syntax.getActions(registered_identifier); begin == end)
207  {
208  _errors.emplace_back(
209  "section '[" + curr_identifier +
210  "]' does not have an associated Action; you likely misspelled the Action/section name "
211  "or the app you are running does not support this Action/syntax",
212  n);
213  return;
214  }
215 
216  // The DynamicObjecRegistrationAction changes the action multimap and would invalidate the
217  // iterators returned by _syntax.getActions, that's why we have to loop in this awkward way.
218  std::set<const Syntax::ActionInfo *> processed_actions;
219  while (true)
220  {
221  // search for an unprocessed action
222  auto [begin, end] = _syntax.getActions(registered_identifier);
223  auto it = begin;
224  for (; it != end && processed_actions.count(&it->second); ++it)
225  ;
226 
227  // no more unprocessed actions
228  if (it == end)
229  break;
230 
231  // mark action as processed
232  processed_actions.insert(&it->second);
233 
234  if (is_parent)
235  continue;
236  if (_syntax.isDeprecatedSyntax(registered_identifier))
238  hit::errormsg(n, _syntax.deprecatedActionSyntaxMessage(registered_identifier)));
239 
240  params = _action_factory.getValidParams(it->second._action);
241  params.set<ActionWarehouse *>("awh") = &_action_wh;
242  params.setHitNode(*n, {});
243 
244  extractParams(n, params);
245 
246  // Add the parsed syntax to the parameters object for consumption by the Action
247  params.set<std::string>("task") = it->second._task;
248  params.set<std::string>("registered_identifier") = registered_identifier;
249 
250  if (!(params.have_parameter<bool>("isObjectAction") && params.get<bool>("isObjectAction")))
251  params.set<std::vector<std::string>>("control_tags")
252  .push_back(MooseUtils::baseName(curr_identifier));
253 
254  // Create the Action
255  std::shared_ptr<Action> action_obj =
256  _action_factory.create(it->second._action, curr_identifier, params);
257 
258  {
259  // extract the MooseObject params if necessary
260  std::shared_ptr<MooseObjectAction> object_action =
262  if (object_action)
263  {
264  auto & object_params = object_action->getObjectParams();
265  object_params.setHitNode(*n, {});
266  extractParams(n, object_params);
267  object_params.set<std::vector<std::string>>("control_tags")
268  .push_back(MooseUtils::baseName(curr_identifier));
269  }
270  // extract the Component params if necessary
271  std::shared_ptr<AddActionComponentAction> component_action =
273  if (component_action)
274  {
275  auto & component_params = component_action->getComponentParams();
276  component_params.setHitNode(*n, {});
277  extractParams(n, component_params);
278  component_params.set<std::vector<std::string>>("control_tags")
279  .push_back(MooseUtils::baseName(curr_identifier));
280  }
281  }
282 
283  // add it to the warehouse
284  _action_wh.addActionBlock(action_obj);
285  }
286 }
287 
288 void
289 Builder::walk(const std::string & fullpath, const std::string & nodepath, hit::Node * n)
290 {
291  // skip sections that were manually processed first.
292  if (std::find(_secs_need_first.begin(), _secs_need_first.end(), nodepath) !=
293  _secs_need_first.end())
294  return;
295 
296  walkRaw(fullpath, nodepath, n);
297 }
298 
299 void
301 {
302  // Pull in extracted variables from the parser (fparse stuff)
304 
305  // There are a few order dependent actions that have to be built first in
306  // order for the parser and application to function properly
307  const auto need_action_syntax_first = [this](const auto & action_name)
308  {
309  const auto syntax = _syntax.getSyntaxByAction(action_name);
310  mooseAssert(syntax.size(), "Empty syntax");
311  std::copy(syntax.begin(), syntax.end(), std::back_inserter(_secs_need_first));
312  };
313 
314  // SetupDebugAction: This action can contain an option for monitoring the
315  // parser progress. It must be parsed first to capture all of the parsing
316  // output progress.
317  need_action_syntax_first("SetupDebugAction");
318 
319  // GlobalParamsAction: This action is checked during the parameter extraction
320  // routines of all subsequent blocks. It must be parsed early since it must
321  // exist during subsequent parameter extraction.
322  need_action_syntax_first("GlobalParamsAction");
323 
324  // DynamicObjectRegistration: This action must be built before any MooseObjectActions
325  // are built. This is because we retrieve valid parameters from the Factory
326  // during parse time. Objects must be registered before validParameters can be retrieved.
327  need_action_syntax_first("DynamicObjectRegistrationAction");
328 
329  // Walk all the sections extracting paramters from each into InputParameters objects
330  for (const auto & sec : _secs_need_first)
331  if (auto n = _root.find(sec))
332  walkRaw(n->parent()->fullpath(), n->path(), n);
333 
334  // Walk for the remainder
335  _root.walk(this, hit::NodeType::Section);
336 
337  // Warn for all deprecated parameters together
338  if (_deprecated_params.size())
339  {
340  std::vector<std::string> messages;
341  for (const auto & key_message_pair : _deprecated_params)
342  messages.push_back(key_message_pair.second);
343  const auto message = MooseUtils::stringJoin(messages, "\n\n");
344 
345  const auto current_show_trace = Moose::show_trace;
346  Moose::show_trace = false;
347  moose::internal::mooseDeprecatedStream(Moose::out, false, true, message + "\n\n");
348  Moose::show_trace = current_show_trace;
349  }
350 
351  if (_errors.size())
353 }
354 
355 // Checks the input and the way it has been used and emits any errors/warnings.
356 // This has to be a separate function because for we don't know if some parameters were unused
357 // until all the multiapps/subapps have been fully initialized - which isn't complete until
358 // *after* all the other member functions on Parser have been run. So this is here to be
359 // externally called at the right time.
360 void
361 Builder::errorCheck(const Parallel::Communicator & comm, bool warn_unused, bool err_unused)
362 {
363  // Nothing to do here
364  if (!warn_unused && !err_unused)
365  return;
366 
367  std::vector<hit::ErrorMessage> messages;
368 
369  {
370  UnusedWalker uw(_extracted_vars, *this);
371  _parser.getCommandLineRoot().walk(&uw);
372  Parser::appendErrorMessages(messages, uw.errors);
373  }
374 
375  {
376  UnusedWalker uw(_extracted_vars, *this);
377  _root.walk(&uw);
378  Parser::appendErrorMessages(messages, uw.errors);
379  }
380 
381  for (const auto & arg : _app.commandLine()->unusedHitParams(comm))
382  messages.emplace_back("unused command line parameter '" + arg + "'");
383 
384  if (messages.size())
385  {
386  const auto message = _parser.joinErrorMessages(messages);
387  if (warn_unused)
388  mooseUnused(message);
389  if (err_unused)
390  {
391  if (_parser.getThrowOnError())
392  _parser.parseError(messages);
393  else
394  mooseError(
395  message +
396  "\n\nAppend --allow-unused (or -w) on the command line to ignore unused parameters.");
397  }
398  }
399 }
400 
401 void
403 {
404  switch (type)
405  {
406  case INPUT_FILE:
407  _syntax_formatter = std::make_unique<InputFileFormatter>(dump_mode);
408  break;
409  case YAML:
410  _syntax_formatter = std::make_unique<YAMLFormatter>(dump_mode);
411  break;
412  default:
413  mooseError("Unrecognized Syntax Formatter requested");
414  break;
415  }
416 }
417 
418 void
420 {
421  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
422 
423  for (const auto & iter : _syntax.getAssociatedTypes())
424  root.addSyntaxType(iter.first, iter.second);
425 
426  // Build a list of all the actions appearing in the syntax
427  for (const auto & iter : _syntax.getAssociatedActions())
428  {
429  Syntax::ActionInfo act_info = iter.second;
435  if (act_info._task == "")
436  act_info._task = _action_factory.getTaskName(act_info._action);
437 
438  all_names.push_back(std::make_pair(iter.first, act_info));
439  }
440 
441  // Add all the actions to the JSON tree, except for ActionComponents (below)
442  for (const auto & act_names : all_names)
443  {
444  const auto & act_info = act_names.second;
445  const std::string & action = act_info._action;
446  const std::string & task = act_info._task;
447  const std::string syntax = act_names.first;
448  InputParameters action_obj_params = _action_factory.getValidParams(action);
449  bool params_added = root.addParameters("",
450  syntax,
451  false,
452  action,
453  true,
454  &action_obj_params,
455  _syntax.getLineInfo(syntax, action, ""),
456  "");
457 
458  if (params_added)
459  {
460  auto tasks = _action_factory.getTasksByAction(action);
461  for (auto & t : tasks)
462  {
463  auto info = _action_factory.getLineInfo(action, t);
464  root.addActionTask(syntax, action, t, info);
465  }
466  }
467 
473  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
474  action_obj_params.get<bool>("isObjectAction"))
475  {
476  for (auto & [moose_obj_name, obj] : _factory.registeredObjects())
477  {
478  auto moose_obj_params = obj->buildParameters();
479  // Now that we know that this is a MooseObjectAction we need to see if it has been
480  // restricted
481  // in any way by the user.
482  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
483 
484  // See if the current Moose Object syntax belongs under this Action's block
485  if ((buildable_types.empty() || // Not restricted
486  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
487  buildable_types.end()) && // Restricted but found
488  moose_obj_params.hasBase() && // Has a registered base
489  _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
490  task) && // and that base is associated
491  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
492  )
493  {
494  std::string name;
495  size_t pos = 0;
496  bool is_action_params = false;
497  bool is_type = false;
498  if (syntax[syntax.size() - 1] == '*')
499  {
500  pos = syntax.size();
501 
502  if (!action_obj_params.collapseSyntaxNesting())
503  name = syntax.substr(0, pos - 1) + moose_obj_name;
504  else
505  {
506  name = syntax.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
507  is_action_params = true;
508  }
509  }
510  else
511  {
512  name = syntax + "/<type>/" + moose_obj_name;
513  is_type = true;
514  }
515  moose_obj_params.set<std::string>("type") = moose_obj_name;
516 
517  auto lineinfo = _factory.getLineInfo(moose_obj_name);
518  std::string classname = _factory.associatedClassName(moose_obj_name);
519  root.addParameters(syntax,
520  name,
521  is_type,
522  moose_obj_name,
523  is_action_params,
524  &moose_obj_params,
525  lineinfo,
526  classname);
527  }
528  }
529 
530  // Same thing for ActionComponents, which, while they are not MooseObjects, should behave
531  // similarly syntax-wise
532  if (syntax != "ActionComponents/*")
533  continue;
534 
535  auto iters = _action_factory.getActionsByTask("list_component");
536 
537  for (auto it = iters.first; it != iters.second; ++it)
538  {
539  // Get the name and parameters
540  const auto component_name = it->second;
541  auto component_params = _action_factory.getValidParams(component_name);
542 
543  // We currently do not have build-type restrictions on this action that adds
544  // action-components
545 
546  // See if the current Moose Object syntax belongs under this Action's block
547  if (action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
548  )
549  {
550  // The logic for Components is a little simpler here for now because syntax like
551  // Executioner/TimeIntegrator/type= do not exist for components
552  std::string name;
553  if (syntax[syntax.size() - 1] == '*')
554  {
555  size_t pos = syntax.size();
556  name = syntax.substr(0, pos - 1) + component_name;
557  }
558  component_params.set<std::string>("type") = component_name;
559 
560  auto lineinfo = _action_factory.getLineInfo(component_name, "list_component");
561  // We add the parameters as for an object, because we want to fit them to be
562  // added to json["AddActionComponentAction"]["subblock_types"]
563  root.addParameters(syntax,
564  /*syntax_path*/ name,
565  /*is_type*/ false,
566  "AddActionComponentAction",
567  /*is_action=*/false,
568  &component_params,
569  lineinfo,
570  component_name);
571  }
572  }
573  }
574  }
575  root.addGlobal();
576 }
577 
578 void
579 Builder::buildFullTree(const std::string & search_string)
580 {
581  std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
582 
583  for (const auto & iter : _syntax.getAssociatedActions())
584  {
585  Syntax::ActionInfo act_info = iter.second;
591  if (act_info._task == "")
592  act_info._task = _action_factory.getTaskName(act_info._action);
593 
594  all_names.push_back(std::pair<std::string, Syntax::ActionInfo>(iter.first, act_info));
595  }
596 
597  for (const auto & act_names : all_names)
598  {
599  InputParameters action_obj_params = _action_factory.getValidParams(act_names.second._action);
600  _syntax_formatter->insertNode(
601  act_names.first, act_names.second._action, true, &action_obj_params);
602 
603  const std::string & task = act_names.second._task;
604  std::string act_name = act_names.first;
605 
611  if (action_obj_params.have_parameter<bool>("isObjectAction") &&
612  action_obj_params.get<bool>("isObjectAction"))
613  {
614  for (const auto & [moose_obj_name, obj] : _factory.registeredObjects())
615  {
616  auto moose_obj_params = obj->buildParameters();
621  const std::vector<std::string> & buildable_types = action_obj_params.getBuildableTypes();
622 
623  // See if the current Moose Object syntax belongs under this Action's block
624  if ((buildable_types.empty() || // Not restricted
625  std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
626  buildable_types.end()) && // Restricted but found
627  moose_obj_params.hasBase() && // Has a registered base
628  _syntax.verifyMooseObjectTask(moose_obj_params.getBase(),
629  task) && // and that base is associated
630  action_obj_params.mooseObjectSyntaxVisibility() // and the Action says it's visible
631  )
632  {
633  std::string name;
634  size_t pos = 0;
635  bool is_action_params = false;
636  if (act_name[act_name.size() - 1] == '*')
637  {
638  pos = act_name.size();
639 
640  if (!action_obj_params.collapseSyntaxNesting())
641  name = act_name.substr(0, pos - 1) + moose_obj_name;
642  else
643  {
644  name = act_name.substr(0, pos - 1) + "/<type>/" + moose_obj_name;
645  is_action_params = true;
646  }
647  }
648  else
649  {
650  name = act_name + "/<type>/" + moose_obj_name;
651  }
652 
653  moose_obj_params.set<std::string>("type") = moose_obj_name;
654 
655  _syntax_formatter->insertNode(name, moose_obj_name, is_action_params, &moose_obj_params);
656  }
657  }
658  }
659  }
660 
661  // Do not change to _console, we need this printed to the stdout in all cases
662  Moose::out << _syntax_formatter->print(search_string) << std::flush;
663 }
664 
665 void
666 Builder::extractParams(const hit::Node * const section_node, InputParameters & p)
667 {
668  if (section_node)
669  mooseAssert(section_node->type() == hit::NodeType::Section, "Node type should be a section");
670 
671  for (const auto & [name, par_unique_ptr] : p)
672  {
673  if (p.shouldIgnore(name))
674  continue;
675 
676  const hit::Node * param_node = nullptr;
677 
678  for (const auto & param_name : p.paramAliases(name))
679  {
680  // Check for parameters under the given section, if a section
681  // node was provided
682  if (section_node)
683  {
684  if (const auto section_param_node = section_node->find(param_name);
685  section_param_node && section_param_node->type() == hit::NodeType::Field &&
686  section_param_node->parent() == section_node)
687  param_node = section_param_node;
688  }
689  // No node found within the given section, check [GlobalParams]
690  if (!param_node && queryGlobalParamsNode())
691  {
692  if (const auto global_node = queryGlobalParamsNode()->find(param_name);
693  global_node && global_node->type() == hit::NodeType::Field &&
694  global_node->parent() == queryGlobalParamsNode())
695  {
696  mooseAssert(isGlobal(*global_node), "Could not detect global-ness");
697  param_node = global_node;
698  }
699  }
700 
701  // Found it
702  if (param_node)
703  {
704  const auto fullpath = param_node->fullpath();
705  p.setHitNode(param_name, *param_node, {});
706  p.set_attributes(param_name, false);
707  _extracted_vars.insert(fullpath);
708 
709  const auto global = isGlobal(*param_node);
710 
711  // Check for deprecated parameters if the parameter is not a global param
712  if (!global)
713  if (const auto deprecated_message = p.queryDeprecatedParamMessage(param_name))
714  {
715  std::string key = "";
716  if (const auto object_type_ptr = p.queryObjectType())
717  key += *object_type_ptr + "_";
718  key += param_name;
719  _deprecated_params.emplace(key, *deprecated_message);
720  }
721 
722  // Private parameter, don't set
723  if (p.isPrivate(param_name))
724  {
725  // Error if it isn't global, just once
726  if (!global && std::find_if(_errors.begin(),
727  _errors.end(),
728  [&param_node](const auto & err)
729  { return err.node == param_node; }) == _errors.end())
730  _errors.emplace_back("parameter '" + fullpath + "' is private and cannot be set",
731  param_node);
732  continue;
733  }
734 
735  // Set the value, capturing errors
736  const auto param_field = dynamic_cast<const hit::Field *>(param_node);
737  mooseAssert(param_field, "Is not a field");
738  bool set_param = false;
739  try
740  {
741  ParameterRegistry::get().set(*par_unique_ptr, *param_field);
742  set_param = true;
743  }
744  catch (hit::Error & e)
745  {
746  _errors.emplace_back(e.message, param_node);
747  }
748  catch (std::exception & e)
749  {
750  _errors.emplace_back(e.what(), param_node);
751  }
752 
753  // Break if we failed here and don't perform extra checks
754  if (!set_param)
755  break;
756 
757  // Special setup for vector<VariableName>
758  if (auto cast_par = dynamic_cast<InputParameters::Parameter<std::vector<VariableName>> *>(
759  par_unique_ptr.get()))
760  if (const auto error = p.setupVariableNames(cast_par->set(), *param_node, {}))
761  _errors.emplace_back(*error, param_node);
762 
763  // Possibly perform a range check if this parameter has one
764  if (p.isRangeChecked(param_node->path()))
765  if (const auto error = p.parameterRangeCheck(
766  *par_unique_ptr, param_node->fullpath(), param_node->path(), true))
767  _errors.emplace_back(error->second, param_node);
768 
769  // Don't check the other alises since we've found it
770  break;
771  }
772  }
773 
774  // Special casing when the parameter was not found
775  if (!param_node)
776  {
777  // In the case where we have OutFileName but it wasn't actually found in the input filename,
778  // we will populate it with the actual parsed filename which is available here in the
779  // parser.
780  if (auto out_par_ptr =
781  dynamic_cast<InputParameters::Parameter<OutFileBase> *>(par_unique_ptr.get()))
782  {
783  const auto input_file_name = getPrimaryFileName();
784  mooseAssert(input_file_name.size(), "Input Filename is empty");
785  const auto pos = input_file_name.find_last_of('.');
786  mooseAssert(pos != std::string::npos, "Unable to determine suffix of input file name");
787  out_par_ptr->set() = input_file_name.substr(0, pos) + "_out";
788  p.set_attributes(name, false);
789  }
790  }
791  }
792 
793  // See if there are any auto build vectors that need to be created
794  for (const auto & [param_name, base_name_num_repeat_pair] : p.getAutoBuildVectors())
795  {
796  const auto & [base_name, num_repeat] = base_name_num_repeat_pair;
797  // We'll autogenerate values iff the requested vector is not valid but both the base and
798  // number are valid
799  if (!p.isParamValid(param_name) && p.isParamValid(base_name) && p.isParamValid(num_repeat))
800  {
801  const auto vec_size = p.get<unsigned int>(num_repeat);
802  const std::string & name = p.get<std::string>(base_name);
803 
804  std::vector<VariableName> variable_names(vec_size);
805  for (const auto i : index_range(variable_names))
806  {
807  std::ostringstream oss;
808  oss << name << i;
809  variable_names[i] = oss.str();
810  }
811 
812  // Finally set the autogenerated vector into the InputParameters object
813  p.set<std::vector<VariableName>>(param_name) = variable_names;
814  }
815  }
816 }
817 
818 void
819 Builder::extractParams(const std::string & prefix, InputParameters & p)
820 {
821  const auto node = _root.find(prefix);
822  extractParams((node && node->type() == hit::NodeType::Section) ? node : nullptr, p);
823 }
824 
825 bool
826 Builder::isGlobal(const hit::Node & node) const
827 {
828  const auto global_params_node = queryGlobalParamsNode();
829  return global_params_node && node.parent() == global_params_node;
830 }
831 
832 const hit::Node *
834 {
835  if (!_global_params_node)
836  {
837  const auto syntax = _syntax.getSyntaxByAction("GlobalParamsAction");
838  mooseAssert(syntax.size() == 1, "Unexpected GlobalParamsAction syntax size");
839  _global_params_node = _root.find(syntax.front());
840  }
841  return *_global_params_node;
842 }
843 
844 } // end of namespace Moose
std::string name(const ElemQuality q)
OStreamProxy err
void build()
Parse an input file (or text string if provided) consisting of hit syntax and setup objects in the MO...
Definition: Builder.C:300
void addSyntaxType(const std::string &path, const std::string type)
Add an associated type to a block.
ActionFactory & _action_factory
The Factory that builds actions.
Definition: Builder.h:139
MooseApp & _app
The MooseApp this Parser is part of.
Definition: Builder.h:133
const std::multimap< std::string, std::string > & getAssociatedTypes() const
Get a multimap of registered associations of syntax with type.
Definition: Syntax.C:368
void walk(const std::string &fullpath, const std::string &nodename, hit::Node *n) override
Definition: Builder.C:159
bool show_trace
Set to true (the default) to print the stack trace with error and warning messages - false to omit it...
Definition: Moose.C:794
std::pair< std::multimap< std::string, ActionInfo >::const_iterator, std::multimap< std::string, ActionInfo >::const_iterator > getActions(const std::string &syntax) const
Returns a pair of multimap iterators to all the ActionInfo objects associated with a given piece of s...
Definition: Syntax.C:328
void walkRaw(std::string fullpath, std::string nodepath, hit::Node *n)
Definition: Builder.C:186
void parseError(std::vector< hit::ErrorMessage > messages) const
Helper for throwing an error with the given messages.
Definition: Parser.C:493
Parser & _parser
The front parser.
Definition: Builder.h:143
InputParameters & getComponentParams()
Return the parameters of the component.
const std::multimap< std::string, ActionInfo > & getAssociatedActions() const
Return all Syntax to Action associations.
Definition: Syntax.C:374
void buildFullTree(const std::string &search_string)
Use MOOSE Factories to construct a full parse tree for documentation or echoing input.
Definition: Builder.C:579
MPI_Info info
void mooseObjectSyntaxVisibility(bool visibility)
Mutators for controlling whether or not the outermost level of syntax will be collapsed when printed...
void set(libMesh::Parameters::Value &value, const hit::Field &field) const
Sets a parameter value given a hit field.
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:94
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
void addActionTask(const std::string &path, const std::string &action, const std::string &task, const FileLineInfo &lineinfo)
Add a task to the tree.
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
Definition: MooseApp.h:411
std::vector< std::string > _secs_need_first
The sections that we need to execute first (read during the final walk)
Definition: Builder.h:154
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
std::string associatedClassName(const std::string &name) const
Get the associated class name for an object name.
Definition: Factory.C:272
std::pair< std::multimap< std::string, std::string >::const_iterator, std::multimap< std::string, std::string >::const_iterator > getActionsByTask(const std::string &task) const
Returns begin and end iterators in a multimap from tasks to actions names.
char ** vars
std::set< std::string > getTasksByAction(const std::string &action) const
std::string opt
const std::vector< std::string > & getBuildableTypes() const
Returns the list of buildable types as a std::vector<std::string>
Builder(MooseApp &app, ActionWarehouse &action_wh, Parser &parser)
Definition: Builder.C:105
FileLineInfo getLineInfo(const std::string &syntax, const std::string &action, const std::string &task) const
Gets the file and line where the syntax/action/task combo was registered.
Definition: Syntax.C:380
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
Builder & _builder
Definition: Builder.h:50
static InputParameters validParams()
Parameters that are processed directly by the Parser and are valid anywhere in the input...
Definition: Builder.C:121
Base class for MOOSE-based applications.
Definition: MooseApp.h:96
Storage for action instances.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
FileLineInfo getLineInfo(const std::string &name, const std::string &task) const
Gets file and line information where an action was registered.
const std::set< std::string > & getExtractedVars() const
Definition: Parser.h:206
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
Action for creating component actions.
std::unique_ptr< SyntaxTree > _syntax_formatter
Object for holding the syntax parse tree.
Definition: Builder.h:148
Holds the syntax in a Json::Value tree.
std::string _action
Definition: Syntax.h:26
FileLineInfo getLineInfo(const std::string &name) const
Gets file and line information where an object was initially registered.
Definition: Factory.C:260
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:40
InputParameters emptyInputParameters()
void extractParams(const hit::Node *const section_node, InputParameters &p)
Attempt to extract values from input starting with the section in input in section_node based on the ...
Definition: Builder.C:666
std::vector< std::string > getSyntaxByAction(const std::string &action, const std::string &task="")
Retrieve the syntax associated with the passed in action type string.
Definition: Syntax.C:211
static void appendErrorMessages(std::vector< hit::ErrorMessage > &to, const std::vector< hit::ErrorMessage > &from)
Helper for accumulating errors from a walker into an accumulation of errors.
Definition: Parser.C:471
bool isDeprecatedSyntax(const std::string &syntax) const
Returns a Boolean indicating whether the syntax has been deprecated through a call to deprecateAction...
Definition: Syntax.C:205
static InputParameters validParams()
Definition: Action.C:26
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
hit::Node & _root
The root node from the Parser.
Definition: Builder.h:145
std::set< std::string > _extracted_vars
The set of all variables extracted from the input file.
Definition: Builder.h:151
bool addParameters(const std::string &parent_path, const std::string &path, bool is_type, const std::string &action, bool is_action, InputParameters *params, const FileLineInfo &lineinfo, const std::string &classname)
Add parameters to the tree.
static std::string joinErrorMessages(const std::vector< hit::ErrorMessage > &error_messages)
Helper for combining error messages into a single, newline separated message.
Definition: Parser.C:484
void mooseUnused(Args &&... args)
Warning message used to notify the users of unused parts of their input files Really used internally ...
Definition: MooseError.h:366
void initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
Creates a syntax formatter for printing.
Definition: Builder.C:402
bool getThrowOnError() const
Definition: Parser.h:199
static InputParameters validParams()
Definition: EmptyAction.C:19
An inteface for the _console for outputting to the Console object.
void buildJsonSyntaxTree(JsonSyntaxTree &tree) const
Use MOOSE Factories to construct a parameter tree for documentation or echoing input.
Definition: Builder.C:419
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:374
void errorCheck(const libMesh::Parallel::Communicator &comm, bool warn_unused, bool err_unused)
Definition: Builder.C:361
const auto & registeredObjects() const
Returns a reference to the map from names to RegistryEntryBase pointers.
Definition: Factory.h:147
std::string getPrimaryFileName(bool stripLeadingPath=true) const
Return the primary (first) filename that was parsed.
Definition: Builder.C:179
std::vector< hit::ErrorMessage > errors
Definition: Builder.h:46
bool isGlobal(const hit::Node &node) const
Definition: Builder.C:826
void mooseDeprecatedStream(S &oss, const bool expired, const bool print_title, Args &&... args)
Definition: MooseError.h:265
std::vector< hit::ErrorMessage > _errors
The errors accumulated during the walk.
Definition: Builder.h:157
std::string isAssociated(const std::string &real_id, bool *is_parent, const std::map< std::string, std::set< std::string >> &alt_map={}) const
Method for determining whether a piece of syntax is associated with an Action an optional syntax map ...
Definition: Syntax.C:251
std::string getTaskName(const std::string &action)
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
std::string _task
Definition: Syntax.h:27
std::map< std::string, std::string > _deprecated_params
Deprecation warnings (object type/param name) -> (message)
Definition: Builder.h:160
std::string baseName(const std::string &name)
Function for string the information before the final / in a parser block.
Definition: MooseUtils.C:614
Syntax & _syntax
Reference to an object that defines input file syntax.
Definition: Builder.h:141
std::set< std::string > _used
Definition: Builder.h:49
const hit::Node & getCommandLineRoot() const
Definition: Parser.C:457
void addGlobal()
Add the global section to the output.
int levenshteinDist(const std::string &s1, const std::string &s2)
Computes and returns the Levenshtein distance between strings s1 and s2.
Definition: MooseUtils.C:172
bool verifyMooseObjectTask(const std::string &base, const std::string &task) const
Returns a Boolean indicating whether a task is associated with on of the MOOSE pluggable systems (BAS...
Definition: Syntax.C:334
std::vector< std::string > findSimilar(const std::string &param, const std::vector< std::string > &options)
Definition: Builder.C:80
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
Factory & _factory
The Factory associated with that MooseApp.
Definition: Builder.h:135
virtual ~Builder()
Definition: Builder.C:118
std::vector< std::string > listValidParams(std::string &section_name)
Definition: Builder.C:142
void setHitNode(const std::string &param, const hit::Node &node, const SetParamHitNodeKey)
Sets the hit node associated with the parameter param to node.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
std::filesystem::path getLastInputFilePath() const
Definition: Parser.h:185
ActionWarehouse & _action_wh
Action warehouse that will be filled by actions.
Definition: Builder.h:137
std::string deprecatedActionSyntaxMessage(const std::string syntax)
Returns the deprecation message for a given syntax that has been deprecated by deprecateActionSyntax...
Definition: Syntax.C:194
void collapseSyntaxNesting(bool collapse)
Mutators for controlling whether or not the outermost level of syntax will be collapsed when printed...
const hit::Node * queryGlobalParamsNode() const
Get the [GlobalParams] section node if it exists.
Definition: Builder.C:833
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
Definition: MooseUtils.C:951
auto index_range(const T &sizable)
Class for parsing input files.
Definition: Parser.h:87
static ParameterRegistry & get()
Get the singleton registry.
std::optional< const hit::Node * > _global_params_node
The hit Node for the [GlobalParams] block, if any If set (could be null), it means we have searched f...
Definition: Builder.h:164
bool isSectionActive(const hit::Node &node)
Definition: Builder.C:45
void walk(const std::string &fullpath, const std::string &nodepath, hit::Node *n)
Definition: Builder.C:289