CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ParameterDescriptionNode.h
Go to the documentation of this file.
1 #ifndef FWCore_ParameterSet_ParameterDescriptionNode_h
2 #define FWCore_ParameterSet_ParameterDescriptionNode_h
3 
4 // This is a base class for the class that describes
5 // the parameters that are allowed or required to be
6 // in a ParameterSet. It is also a base class for
7 // other more complex logical structures which describe
8 // which combinations of parameters are allowed to be
9 // in a ParameterSet.
10 
12 
13 #include <string>
14 #include <set>
15 #include <iosfwd>
16 #include <memory>
17 
18 namespace edm {
19 
20  class ParameterSet;
21  template <typename T> class ParameterDescriptionCases;
22  class DocFormatHelper;
23 
24  // Originally these were defined such that the values were the
25  // same as in the ParameterSet Entry class and the validation
26  // depended on that. But at the moment I'm typing this comment,
27  // the code no longer depends on the values being the same (which
28  // is probably good because nothing enforces the correspondence,
29  // a task for the future when someone has free time would be
30  // to define the values in a common header, but that would involve
31  // significant changes to ParameterSet ...)
33  k_int32 = 'I',
34  k_vint32 = 'i',
35  k_uint32 = 'U',
36  k_vuint32 = 'u',
37  k_int64 = 'L',
38  k_vint64 = 'l',
39  k_uint64 = 'X',
40  k_vuint64 = 'x',
41  k_double = 'D',
42  k_vdouble = 'd',
43  k_bool = 'B',
44  k_string = 'S',
45  k_vstring = 's',
46  k_EventID = 'E',
47  k_VEventID = 'e',
50  k_InputTag = 't',
51  k_VInputTag = 'v',
52  k_FileInPath = 'F',
55  k_EventRange = 'R',
57  k_PSet = 'Q',
58  k_VPSet = 'q'
59  };
60 
61  std::string parameterTypeEnumToString(ParameterTypes iType);
62 
64  template <class T>
65  static ParameterTypes toEnum();
66  };
67 
68 
70 
71  public:
72 
73  virtual ~ParameterDescriptionNode();
74 
75  virtual ParameterDescriptionNode* clone() const = 0;
76 
77  std::string const& comment() const { return comment_; }
78  void setComment(std::string const & value);
79  void setComment(char const* value);
80 
81  // The validate function should do one of three things, find that the
82  // node "exists", make the node "exist" by inserting missing parameters
83  // or throw. The only exception to this rule occurs when the argument
84  // named "optional" is true, which should only be possible for the
85  // top level nodes of a ParameterSetDescription. When a parameter is
86  // found or inserted its label is added into the list of validatedLabels.
88  std::set<std::string> & validatedLabels,
89  bool optional) const {
90  validate_(pset, validatedLabels, optional);
91  }
92 
93  // As long as it has default values, this will attempt to write
94  // parameters associated with a node into a cfi file that is
95  // being automatically generated. It is quite possible for
96  // to produce a cfi that will fail validation. In some cases,
97  // this will imply the user is required to supply certain missing
98  // parameters that do not appear in the cfi and do not have defaults
99  // in the description. It is also possible to create a pathological
100  // ParameterSetDescription where the algorithm fails to write
101  // a valid cfi, in some cases the description can be so pathological
102  // that it is impossible to write a cfi that will pass validation.
103  void writeCfi(std::ostream & os,
104  bool & startWithComma,
105  int indentation,
106  bool & wroteSomething) const {
107  writeCfi_(os, startWithComma, indentation, wroteSomething);
108  }
109 
110  // Print out the description in human readable format
111  void print(std::ostream & os,
112  bool optional,
113  bool writeToCfi,
114  DocFormatHelper & dfh);
115 
117  return hasNestedContent_();
118  }
119 
120  void printNestedContent(std::ostream & os,
121  bool optional,
122  DocFormatHelper & dfh);
123 
124  // The next three functions are only called by the logical nodes
125  // on their subnodes. When executing these functions, the
126  // insertion of missing parameters does not occur.
127 
128  // Usually checks to see if a parameter exists in the configuration, but
129  // if the node is a logical node, then it returns the value of the logical
130  // expression.
131  bool exists(ParameterSet const& pset) const {
132  return exists_(pset);
133  }
134 
135  // For most nodes, this simply returns the same value as the exists
136  // function. But for AND nodes this returns true if either its subnodes
137  // exists. Used by operator&& during validation, if either of an AND node's
138  // subnodes exists, then both subnodes get validated.
139  bool partiallyExists(ParameterSet const& pset) const {
140  return partiallyExists_(pset);
141  }
142 
143  // For most nodes, this simply returns the same value as the exists
144  // function. It is different for an XOR node. It counts
145  // XOR subnodes whose exists function returns true. And it
146  // does this recursively into XOR nodes that are contained in
147  // other XOR nodes.
148  // Used by operator^ during validation:
149  // -- if it returns more than 1, then validation will throw,
150  // -- if it returns exactly one, then only the nonzero subnode gets validated
151  // -- if it returns zero, then validation tries to validate the first node and
152  // then rechecks to see what the missing parameter insertion did (there could
153  // be side effects on the nodes that were not validated)
155  return howManyXORSubNodesExist_(pset);
156  }
157 
158  /* Validation puts requirements on which parameters can and cannot exist
159  within a ParameterSet. The evaluation of whether a ParameterSet passes
160  or fails the rules in the ParameterSetDescription is complicated by
161  the fact that we allow missing parameters to be injected into the
162  ParameterSet during validation. One must worry whether injecting a
163  missing parameter invalidates some other part of the ParameterSet that
164  was already checked and determined to be OK. The following restrictions
165  avoid that problem.
166 
167  - The same parameter labels cannot occur in different nodes of the
168  same ParameterSetDescription. There are two exceptions to this.
169  Nodes that are contained in the cases of a ParameterSwitch or the
170  subnodes of an "exclusive or" are allowed to use the same labels.
171 
172  - If insertion is necessary to make an "exclusive or" node pass
173  validation, then the insertion could make more than one of the
174  possibilities evaluate true. This must be checked for after the
175  insertions occur. The behavior is to throw a Configuration exception
176  if this problem is encountered. (Example: (A && B) ^ (A && C) where
177  C already exists in the ParameterSet but A and B do not. A and B
178  get inserted by the algorithm, because it tries to make the first
179  possibility true when all fail without insertion. Then both
180  parts of the "exclusive or" pass, which is a validation failure).
181 
182  - Another potential problem is that a parameter insertion related
183  to one ParameterDescription could match unrelated wildcards causing
184  other validation requirements to change from being passing to failing
185  or vice versa. This makes it almost impossible to determine if a
186  ParameterSet passes validation. Each time you try to loop through
187  and check, the result of validation could change. To avoid this problem,
188  a list is maintained of the type for all wildcards. Another list is
189  maintained for the type of all parameters. As new items are added
190  we check for collisions. The function that builds the ParameterSetDescription,
191  will throw if this rule is violated. At the moment, the criteria
192  for a collision is matching types between a parameter and a wildcard.
193  (This criteria is overrestrictive. With some additional CPU and
194  code development the restriction could be loosened to parameters that
195  might be injected cannot match the type, trackiness, and wildcard label
196  pattern of any wildcard that requires a match. And further this
197  could not apply to wildcards on different branches of a ParameterSwitch
198  or "exclusive or".)
199 
200  These restrictions have the additional benefit that the things they prohibit
201  would tend to confuse a user trying to configure a module or a module developer
202  writing the code to extract the parameters from a ParameterSet. These rules
203  tend to prohibit bad design.
204 
205  One strategy to avoid problems with wildcard parameters is to add a nested
206  ParameterSet and put the wildcard parameters in the nested ParameterSet.
207  The names and types in a nested ParameterSet will not interfere with names
208  in the containing ParameterSet.
209  */
210  void checkAndGetLabelsAndTypes(std::set<std::string> & usedLabels,
211  std::set<ParameterTypes> & parameterTypes,
212  std::set<ParameterTypes> & wildcardTypes) const {
213  checkAndGetLabelsAndTypes_(usedLabels, parameterTypes, wildcardTypes);
214  }
215 
216  static void printSpaces(std::ostream & os, int n);
217 
218  protected:
219 
220  virtual void checkAndGetLabelsAndTypes_(std::set<std::string> & usedLabels,
221  std::set<ParameterTypes> & parameterTypes,
222  std::set<ParameterTypes> & wildcardTypes) const = 0;
223 
224  virtual void validate_(ParameterSet & pset,
225  std::set<std::string> & validatedLabels,
226  bool optional) const = 0;
227 
228  virtual void writeCfi_(std::ostream & os,
229  bool & startWithComma,
230  int indentation,
231  bool & wroteSomething) const = 0;
232 
233  virtual void print_(std::ostream & os,
234  bool optional,
235  bool writeToCfi,
236  DocFormatHelper & dfh) { }
237 
238  virtual bool hasNestedContent_() {
239  return false;
240  }
241 
242  virtual void printNestedContent_(std::ostream & os,
243  bool optional,
244  DocFormatHelper & dfh) { }
245 
246  virtual bool exists_(ParameterSet const& pset) const = 0;
247 
248  virtual bool partiallyExists_(ParameterSet const& pset) const = 0;
249 
250  virtual int howManyXORSubNodesExist_(ParameterSet const& pset) const = 0;
251 
252  std::string comment_;
253  };
254 
255  template <>
257  {
258  static ParameterDescriptionNode * clone( ParameterDescriptionNode const * p ) { return p->clone(); }
259  };
260 
261  // operator>> ---------------------------------------------
262 
263  std::auto_ptr<ParameterDescriptionCases<bool> >
264  operator>>(bool caseValue,
265  ParameterDescriptionNode const& node);
266 
267  std::auto_ptr<ParameterDescriptionCases<int> >
268  operator>>(int caseValue,
269  ParameterDescriptionNode const& node);
270 
271  std::auto_ptr<ParameterDescriptionCases<std::string> >
272  operator>>(std::string const& caseValue,
273  ParameterDescriptionNode const& node);
274 
275  std::auto_ptr<ParameterDescriptionCases<std::string> >
276  operator>>(char const* caseValue,
277  ParameterDescriptionNode const& node);
278 
279  std::auto_ptr<ParameterDescriptionCases<bool> >
280  operator>>(bool caseValue,
281  std::auto_ptr<ParameterDescriptionNode> node);
282 
283  std::auto_ptr<ParameterDescriptionCases<int> >
284  operator>>(int caseValue,
285  std::auto_ptr<ParameterDescriptionNode> node);
286 
287  std::auto_ptr<ParameterDescriptionCases<std::string> >
288  operator>>(std::string const& caseValue,
289  std::auto_ptr<ParameterDescriptionNode> node);
290 
291  std::auto_ptr<ParameterDescriptionCases<std::string> >
292  operator>>(char const* caseValue,
293  std::auto_ptr<ParameterDescriptionNode> node);
294 
295  // operator&& ---------------------------------------------
296 
297  std::auto_ptr<ParameterDescriptionNode>
298  operator&&(ParameterDescriptionNode const& node_left,
299  ParameterDescriptionNode const& node_right);
300 
301  std::auto_ptr<ParameterDescriptionNode>
302  operator&&(std::auto_ptr<ParameterDescriptionNode> node_left,
303  ParameterDescriptionNode const& node_right);
304 
305  std::auto_ptr<ParameterDescriptionNode>
306  operator&&(ParameterDescriptionNode const& node_left,
307  std::auto_ptr<ParameterDescriptionNode> node_right);
308 
309  std::auto_ptr<ParameterDescriptionNode>
310  operator&&(std::auto_ptr<ParameterDescriptionNode> node_left,
311  std::auto_ptr<ParameterDescriptionNode> node_right);
312 
313  // operator|| ---------------------------------------------
314 
315  std::auto_ptr<ParameterDescriptionNode>
316  operator||(ParameterDescriptionNode const& node_left,
317  ParameterDescriptionNode const& node_right);
318 
319  std::auto_ptr<ParameterDescriptionNode>
320  operator||(std::auto_ptr<ParameterDescriptionNode> node_left,
321  ParameterDescriptionNode const& node_right);
322 
323  std::auto_ptr<ParameterDescriptionNode>
324  operator||(ParameterDescriptionNode const& node_left,
325  std::auto_ptr<ParameterDescriptionNode> node_right);
326 
327  std::auto_ptr<ParameterDescriptionNode>
328  operator||(std::auto_ptr<ParameterDescriptionNode> node_left,
329  std::auto_ptr<ParameterDescriptionNode> node_right);
330 
331  // operator^ ---------------------------------------------
332 
333  std::auto_ptr<ParameterDescriptionNode>
334  operator^(ParameterDescriptionNode const& node_left,
335  ParameterDescriptionNode const& node_right);
336 
337  std::auto_ptr<ParameterDescriptionNode>
338  operator^(std::auto_ptr<ParameterDescriptionNode> node_left,
339  ParameterDescriptionNode const& node_right);
340 
341  std::auto_ptr<ParameterDescriptionNode>
342  operator^(ParameterDescriptionNode const& node_left,
343  std::auto_ptr<ParameterDescriptionNode> node_right);
344 
345  std::auto_ptr<ParameterDescriptionNode>
346  operator^(std::auto_ptr<ParameterDescriptionNode> node_left,
347  std::auto_ptr<ParameterDescriptionNode> node_right);
348 }
349 #endif
void setComment(std::string const &value)
virtual ParameterDescriptionNode * clone() const =0
virtual bool partiallyExists_(ParameterSet const &pset) const =0
virtual void checkAndGetLabelsAndTypes_(std::set< std::string > &usedLabels, std::set< ParameterTypes > &parameterTypes, std::set< ParameterTypes > &wildcardTypes) const =0
void validate(ParameterSet &pset, std::set< std::string > &validatedLabels, bool optional) const
virtual void printNestedContent_(std::ostream &os, bool optional, DocFormatHelper &dfh)
std::istream & operator>>(std::istream &is, FileInPath &fip)
Definition: FileInPath.h:151
int howManyXORSubNodesExist(ParameterSet const &pset) const
virtual int howManyXORSubNodesExist_(ParameterSet const &pset) const =0
std::string parameterTypeEnumToString(ParameterTypes iType)
static ParameterDescriptionNode * clone(ParameterDescriptionNode const *p)
tuple node
Definition: Node.py:50
boost::enable_if_c< has_match< A >::value &&has_match< B >::value, OrHelper< A, B > >::type operator||(A const &a, B const &b)
Definition: Selector.h:235
virtual void writeCfi_(std::ostream &os, bool &startWithComma, int indentation, bool &wroteSomething) const =0
void printNestedContent(std::ostream &os, bool optional, DocFormatHelper &dfh)
std::string const & comment() const
virtual void print_(std::ostream &os, bool optional, bool writeToCfi, DocFormatHelper &dfh)
static void printSpaces(std::ostream &os, int n)
bool exists(ParameterSet const &pset) const
bool partiallyExists(ParameterSet const &pset) const
void print(std::ostream &os, bool optional, bool writeToCfi, DocFormatHelper &dfh)
virtual void validate_(ParameterSet &pset, std::set< std::string > &validatedLabels, bool optional) const =0
static ParameterTypes toEnum()
boost::enable_if_c< has_match< A >::value &&has_match< B >::value, AndHelper< A, B > >::type operator&&(A const &a, B const &b)
Definition: Selector.h:203
void checkAndGetLabelsAndTypes(std::set< std::string > &usedLabels, std::set< ParameterTypes > &parameterTypes, std::set< ParameterTypes > &wildcardTypes) const
virtual bool exists_(ParameterSet const &pset) const =0
std::auto_ptr< ParameterDescriptionNode > operator^(ParameterDescriptionNode const &node_left, ParameterDescriptionNode const &node_right)
void writeCfi(std::ostream &os, bool &startWithComma, int indentation, bool &wroteSomething) const