00001
00002 #include "FWCore/ParameterSet/interface/XORGroupDescription.h"
00003 #include "FWCore/Utilities/interface/EDMException.h"
00004 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
00005
00006 #include <ostream>
00007 #include <iomanip>
00008
00009 namespace edm {
00010
00011 XORGroupDescription::
00012 XORGroupDescription(ParameterDescriptionNode const& node_left,
00013 ParameterDescriptionNode const& node_right) :
00014 node_left_(node_left.clone()),
00015 node_right_(node_right.clone()) {
00016 }
00017
00018 XORGroupDescription::
00019 XORGroupDescription(std::auto_ptr<ParameterDescriptionNode> node_left,
00020 ParameterDescriptionNode const& node_right) :
00021 node_left_(node_left),
00022 node_right_(node_right.clone()) {
00023 }
00024
00025 XORGroupDescription::
00026 XORGroupDescription(ParameterDescriptionNode const& node_left,
00027 std::auto_ptr<ParameterDescriptionNode> node_right) :
00028 node_left_(node_left.clone()),
00029 node_right_(node_right) {
00030 }
00031
00032 XORGroupDescription::
00033 XORGroupDescription(std::auto_ptr<ParameterDescriptionNode> node_left,
00034 std::auto_ptr<ParameterDescriptionNode> node_right) :
00035 node_left_(node_left),
00036 node_right_(node_right) {
00037 }
00038
00039 void
00040 XORGroupDescription::
00041 checkAndGetLabelsAndTypes_(std::set<std::string> & usedLabels,
00042 std::set<ParameterTypes> & parameterTypes,
00043 std::set<ParameterTypes> & wildcardTypes) const {
00044
00045 std::set<std::string> labelsLeft;
00046 std::set<ParameterTypes> parameterTypesLeft;
00047 std::set<ParameterTypes> wildcardTypesLeft;
00048 node_left_->checkAndGetLabelsAndTypes(labelsLeft, parameterTypesLeft, wildcardTypesLeft);
00049
00050 std::set<std::string> labelsRight;
00051 std::set<ParameterTypes> parameterTypesRight;
00052 std::set<ParameterTypes> wildcardTypesRight;
00053 node_right_->checkAndGetLabelsAndTypes(labelsRight, parameterTypesRight, wildcardTypesRight);
00054
00055 usedLabels.insert(labelsLeft.begin(), labelsLeft.end());
00056 usedLabels.insert(labelsRight.begin(), labelsRight.end());
00057
00058 parameterTypes.insert(parameterTypesRight.begin(), parameterTypesRight.end());
00059 parameterTypes.insert(parameterTypesLeft.begin(), parameterTypesLeft.end());
00060
00061 wildcardTypes.insert(wildcardTypesRight.begin(), wildcardTypesRight.end());
00062 wildcardTypes.insert(wildcardTypesLeft.begin(), wildcardTypesLeft.end());
00063 }
00064
00065 void
00066 XORGroupDescription::
00067 validate_(ParameterSet & pset,
00068 std::set<std::string> & validatedLabels,
00069 bool optional) const {
00070
00071 int nExistLeft = node_left_->howManyXORSubNodesExist(pset);
00072 int nExistRight = node_right_->howManyXORSubNodesExist(pset);
00073 int nTotal = nExistLeft + nExistRight;
00074
00075 if (nTotal == 0 && optional) return;
00076
00077 if (nTotal > 1) {
00078 throwMoreThanOneParameter();
00079 }
00080
00081 if (nExistLeft == 1) {
00082 node_left_->validate(pset, validatedLabels, false);
00083 }
00084 else if (nExistRight == 1) {
00085 node_right_->validate(pset, validatedLabels, false);
00086 }
00087 else if (nTotal == 0) {
00088 node_left_->validate(pset, validatedLabels, false);
00089
00090
00091
00092 nExistLeft = node_left_->howManyXORSubNodesExist(pset);
00093 nExistRight = node_right_->howManyXORSubNodesExist(pset);
00094 nTotal = nExistLeft + nExistRight;
00095
00096 if (nTotal != 1) {
00097 throwAfterValidation();
00098 }
00099 }
00100 }
00101
00102 void
00103 XORGroupDescription::
00104 writeCfi_(std::ostream & os,
00105 bool & startWithComma,
00106 int indentation,
00107 bool & wroteSomething) const {
00108 node_left_->writeCfi(os, startWithComma, indentation, wroteSomething);
00109 }
00110
00111 void
00112 XORGroupDescription::
00113 print_(std::ostream & os,
00114 bool optional,
00115 bool writeToCfi,
00116 DocFormatHelper & dfh) {
00117
00118 if (dfh.parent() == DocFormatHelper::XOR) {
00119 dfh.decrementCounter();
00120 node_left_->print(os, false, true, dfh);
00121 node_right_->print(os, false, true, dfh);
00122 return;
00123 }
00124
00125 if (dfh.pass() == 1) {
00126
00127 dfh.indent(os);
00128 os << "XOR group:";
00129
00130 if (dfh.brief()) {
00131
00132 if (optional) os << " optional";
00133
00134 if (!writeToCfi) os << " (do not write to cfi)";
00135
00136 os << " see Section " << dfh.section() << "." << dfh.counter() << "\n";
00137 }
00138
00139 else {
00140
00141 os << "\n";
00142 dfh.indent2(os);
00143
00144 if (optional) os << "optional";
00145 if (!writeToCfi) os << " (do not write to cfi)";
00146 if (optional || !writeToCfi) {
00147 os << "\n";
00148 dfh.indent2(os);
00149 }
00150
00151 os << "see Section " << dfh.section() << "." << dfh.counter() << "\n";
00152
00153 if (!comment().empty()) {
00154 DocFormatHelper::wrapAndPrintText(os,
00155 comment(),
00156 dfh.startColumn2(),
00157 dfh.commentWidth());
00158 }
00159 os << "\n";
00160 }
00161 }
00162 }
00163
00164 void
00165 XORGroupDescription::
00166 printNestedContent_(std::ostream & os,
00167 bool optional,
00168 DocFormatHelper & dfh) {
00169
00170 if (dfh.parent() == DocFormatHelper::XOR) {
00171 dfh.decrementCounter();
00172 node_left_->printNestedContent(os, false, dfh);
00173 node_right_->printNestedContent(os, false, dfh);
00174 return;
00175 }
00176
00177 int indentation = dfh.indentation();
00178 if (dfh.parent() != DocFormatHelper::TOP) {
00179 indentation -= DocFormatHelper::offsetSectionContent();
00180 }
00181
00182 std::stringstream ss;
00183 ss << dfh.section() << "." << dfh.counter();
00184 std::string newSection = ss.str();
00185
00186 printSpaces(os, indentation);
00187 os << "Section " << newSection
00188 << " XOR group description:\n";
00189 printSpaces(os, indentation);
00190 if (optional) {
00191 os << "This optional XOR group requires exactly one or none of the following to be in the PSet\n";
00192 }
00193 else {
00194 os << "This XOR group requires exactly one of the following to be in the PSet\n";
00195 }
00196 if (!dfh.brief()) os << "\n";
00197
00198 DocFormatHelper new_dfh(dfh);
00199 new_dfh.init();
00200 new_dfh.setSection(newSection);
00201 new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
00202 new_dfh.setParent(DocFormatHelper::XOR);
00203
00204 node_left_->print(os, false, true, new_dfh);
00205 node_right_->print(os, false, true, new_dfh);
00206
00207 new_dfh.setPass(1);
00208 new_dfh.setCounter(0);
00209
00210 node_left_->print(os, false, true, new_dfh);
00211 node_right_->print(os, false, true, new_dfh);
00212
00213 new_dfh.setPass(2);
00214 new_dfh.setCounter(0);
00215
00216 node_left_->printNestedContent(os, false, new_dfh);
00217 node_right_->printNestedContent(os, false, new_dfh);
00218 }
00219
00220 bool
00221 XORGroupDescription::
00222 exists_(ParameterSet const& pset) const {
00223 int nTotal = node_left_->howManyXORSubNodesExist(pset) +
00224 node_right_->howManyXORSubNodesExist(pset);
00225 return nTotal == 1;
00226 }
00227
00228 bool
00229 XORGroupDescription::
00230 partiallyExists_(ParameterSet const& pset) const {
00231 return exists(pset);
00232 }
00233
00234 int
00235 XORGroupDescription::
00236 howManyXORSubNodesExist_(ParameterSet const& pset) const {
00237 return node_left_->howManyXORSubNodesExist(pset) +
00238 node_right_->howManyXORSubNodesExist(pset);
00239 }
00240
00241 void
00242 XORGroupDescription::
00243 throwMoreThanOneParameter() const {
00244
00245
00246
00247 throw edm::Exception(errors::LogicError)
00248 << "Exactly one parameter can exist in a ParameterSet from a list of\n"
00249 << "parameters described by an \"xor\" operator in a ParameterSetDescription.\n"
00250 << "This rule also applies in a more general sense to the other types\n"
00251 << "of nodes that can appear within a ParameterSetDescription. Only one\n"
00252 << "can pass validation as \"existing\".\n";
00253 }
00254
00255 void
00256 XORGroupDescription::
00257 throwAfterValidation() const {
00258
00259
00260
00261 throw edm::Exception(errors::LogicError)
00262 << "Exactly one parameter can exist in a ParameterSet from a list of\n"
00263 << "parameters described by an \"xor\" operator in a ParameterSetDescription.\n"
00264 << "This rule also applies in a more general sense to the other types\n"
00265 << "of nodes that can appear within a ParameterSetDescription. Only one\n"
00266 << "can pass validation as \"existing\". This error has occurred after an\n"
00267 << "attempt to insert missing parameters to fix the problem.\n";
00268 }
00269 }