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 
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&,
234  bool /*optional*/,
235  bool /*writeToCfi*/,
236  DocFormatHelper&) { }
237 
238  virtual bool hasNestedContent_() {
239  return false;
240  }
241 
242  virtual void printNestedContent_(std::ostream&,
243  bool /*optional*/,
244  DocFormatHelper&) { }
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 
253  };
254 
255  template <>
258  };
259 
260  // operator>> ---------------------------------------------
261 
262  std::auto_ptr<ParameterDescriptionCases<bool> >
263  operator>>(bool caseValue,
264  ParameterDescriptionNode const& node);
265 
266  std::auto_ptr<ParameterDescriptionCases<int> >
267  operator>>(int caseValue,
268  ParameterDescriptionNode const& node);
269 
270  std::auto_ptr<ParameterDescriptionCases<std::string> >
271  operator>>(std::string const& caseValue,
272  ParameterDescriptionNode const& node);
273 
274  std::auto_ptr<ParameterDescriptionCases<std::string> >
275  operator>>(char const* caseValue,
276  ParameterDescriptionNode const& node);
277 
278  std::auto_ptr<ParameterDescriptionCases<bool> >
279  operator>>(bool caseValue,
280  std::auto_ptr<ParameterDescriptionNode> node);
281 
282  std::auto_ptr<ParameterDescriptionCases<int> >
283  operator>>(int caseValue,
284  std::auto_ptr<ParameterDescriptionNode> node);
285 
286  std::auto_ptr<ParameterDescriptionCases<std::string> >
287  operator>>(std::string const& caseValue,
288  std::auto_ptr<ParameterDescriptionNode> node);
289 
290  std::auto_ptr<ParameterDescriptionCases<std::string> >
291  operator>>(char const* caseValue,
292  std::auto_ptr<ParameterDescriptionNode> node);
293 
294  // operator&& ---------------------------------------------
295 
296  std::auto_ptr<ParameterDescriptionNode>
297  operator&&(ParameterDescriptionNode const& node_left,
298  ParameterDescriptionNode const& node_right);
299 
300  std::auto_ptr<ParameterDescriptionNode>
301  operator&&(std::auto_ptr<ParameterDescriptionNode> node_left,
302  ParameterDescriptionNode const& node_right);
303 
304  std::auto_ptr<ParameterDescriptionNode>
305  operator&&(ParameterDescriptionNode const& node_left,
306  std::auto_ptr<ParameterDescriptionNode> node_right);
307 
308  std::auto_ptr<ParameterDescriptionNode>
309  operator&&(std::auto_ptr<ParameterDescriptionNode> node_left,
310  std::auto_ptr<ParameterDescriptionNode> node_right);
311 
312  // operator|| ---------------------------------------------
313 
314  std::auto_ptr<ParameterDescriptionNode>
315  operator||(ParameterDescriptionNode const& node_left,
316  ParameterDescriptionNode const& node_right);
317 
318  std::auto_ptr<ParameterDescriptionNode>
319  operator||(std::auto_ptr<ParameterDescriptionNode> node_left,
320  ParameterDescriptionNode const& node_right);
321 
322  std::auto_ptr<ParameterDescriptionNode>
323  operator||(ParameterDescriptionNode const& node_left,
324  std::auto_ptr<ParameterDescriptionNode> node_right);
325 
326  std::auto_ptr<ParameterDescriptionNode>
327  operator||(std::auto_ptr<ParameterDescriptionNode> node_left,
328  std::auto_ptr<ParameterDescriptionNode> node_right);
329 
330  // operator^ ---------------------------------------------
331 
332  std::auto_ptr<ParameterDescriptionNode>
333  operator^(ParameterDescriptionNode const& node_left,
334  ParameterDescriptionNode const& node_right);
335 
336  std::auto_ptr<ParameterDescriptionNode>
337  operator^(std::auto_ptr<ParameterDescriptionNode> node_left,
338  ParameterDescriptionNode const& node_right);
339 
340  std::auto_ptr<ParameterDescriptionNode>
341  operator^(ParameterDescriptionNode const& node_left,
342  std::auto_ptr<ParameterDescriptionNode> node_right);
343 
344  std::auto_ptr<ParameterDescriptionNode>
345  operator^(std::auto_ptr<ParameterDescriptionNode> node_left,
346  std::auto_ptr<ParameterDescriptionNode> node_right);
347 }
348 #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 print_(std::ostream &, bool, bool, DocFormatHelper &)
std::istream & operator>>(std::istream &is, FileInPath &fip)
Definition: FileInPath.h:149
int howManyXORSubNodesExist(ParameterSet const &pset) const
virtual void printNestedContent_(std::ostream &, bool, DocFormatHelper &)
virtual int howManyXORSubNodesExist_(ParameterSet const &pset) const =0
std::string parameterTypeEnumToString(ParameterTypes iType)
static ParameterDescriptionNode * clone(ParameterDescriptionNode const *p)
std::auto_ptr< ParameterDescriptionCases< bool > > operator||(std::auto_ptr< ParameterDescriptionCases< bool > >, std::auto_ptr< ParameterDescriptionCases< bool > >)
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
static void printSpaces(std::ostream &os, int n)
bool exists(ParameterSet const &pset) const
bool partiallyExists(ParameterSet const &pset) const
std::auto_ptr< ParameterDescriptionNode > operator&&(ParameterDescriptionNode const &node_left, ParameterDescriptionNode const &node_right)
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()
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