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