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