CMS 3D CMS Logo

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