CMS 3D CMS Logo

ProductRegistryHelper.cc
Go to the documentation of this file.
1 /*----------------------------------------------------------------------
2 
3 ----------------------------------------------------------------------*/
4 
13 
14 #include <vector>
15 #include <typeindex>
16 
17 namespace edm {
19 
21 
22  namespace {
23  void throwProducesWithoutAbility(const char* runOrLumi, std::string const& productTypeName) {
25  << "Module declares it can produce a product of type \'" << productTypeName << "\'\nin a " << runOrLumi
26  << ", but does not have the ability to produce in " << runOrLumi << "s.\n"
27  << "You must add a template parameter of type Begin" << runOrLumi << "Producer\n"
28  << "or End" << runOrLumi << "Producer to the EDProducer or EDFilter base class\n"
29  << "of the module. Or you could remove the call to the function \'produces\'\n"
30  << "(Note legacy modules are not ever allowed to produce in Runs or Lumis)\n";
31  }
32  } // namespace
33 
34  void ProductRegistryHelper::addToRegistry(TypeLabelList::const_iterator const& iBegin,
35  TypeLabelList::const_iterator const& iEnd,
36  ModuleDescription const& iDesc,
37  ProductRegistry& iReg,
38  ProductRegistryHelper* iProd,
39  bool iIsListener) {
40  std::vector<std::string> missingDictionaries;
41  std::vector<std::string> producedTypes;
42  std::set<std::tuple<BranchType, std::type_index, std::string>> registeredProducts;
43 
44  for (TypeLabelList::const_iterator p = iBegin; p != iEnd; ++p) {
45  if (p->transition_ == Transition::BeginRun || p->transition_ == Transition::EndRun) {
46  if (not iProd->hasAbilityToProduceInRuns()) {
47  throwProducesWithoutAbility("Run", p->typeID_.userClassName());
48  }
49  } else if (p->transition_ == Transition::BeginLuminosityBlock ||
50  p->transition_ == Transition::EndLuminosityBlock) {
51  if (not iProd->hasAbilityToProduceInLumis()) {
52  throwProducesWithoutAbility("LuminosityBlock", p->typeID_.userClassName());
53  }
54  }
55  if (!checkDictionary(missingDictionaries, p->typeID_)) {
56  checkDictionaryOfWrappedType(missingDictionaries, p->typeID_);
57  producedTypes.emplace_back(p->typeID_.className());
58  continue;
59  }
60  auto branchType = convertToBranchType(p->transition_);
61  if (branchType != InEvent) {
62  std::tuple<BranchType, std::type_index, std::string> entry{
63  branchType, p->typeID_.typeInfo(), p->productInstanceName_};
64  if (registeredProducts.end() != registeredProducts.find(entry)) {
65  //ignore registration of items if in both begin and end transitions for now
66  // This is to work around ExternalLHEProducer
67  continue;
68  } else {
69  registeredProducts.insert(entry);
70  }
71  }
72 
73  TypeWithDict type(p->typeID_.typeInfo());
75  iDesc.moduleLabel(),
76  iDesc.processName(),
77  p->typeID_.userClassName(),
78  p->typeID_.friendlyClassName(),
79  p->productInstanceName_,
80  iDesc.moduleName(),
81  iDesc.parameterSetID(),
82  type,
83  true,
84  isEndTransition(p->transition_));
85  if (p->aliasType_ == TypeLabelItem::AliasType::kSwitchAlias) {
86  if (p->branchAlias_.empty()) {
88  << "Branch alias type has been set to SwitchAlias, but the alias content is empty.\n"
89  << "Please report this error to the FWCore developers";
90  }
91  pdesc.setSwitchAliasModuleLabel(p->branchAlias_);
92  }
93  setIsMergeable(pdesc);
94 
95  if (pdesc.transient()) {
96  if (!checkDictionary(missingDictionaries, pdesc.wrappedName(), pdesc.wrappedType())) {
97  // It is should be impossible to get here, because the only way to
98  // make it transient is in the line that causes the wrapped dictionary
99  // to be created. Just to be safe I leave this check here ...
100  producedTypes.emplace_back(pdesc.className());
101  continue;
102  }
103  } else {
104  // also check constituents of wrapped types if it is not transient
105  if (!checkClassDictionaries(missingDictionaries, pdesc.wrappedName(), pdesc.wrappedType())) {
106  producedTypes.emplace_back(pdesc.className());
107  continue;
108  }
109  }
110  if (!p->branchAlias_.empty())
111  pdesc.insertBranchAlias(p->branchAlias_);
112  iReg.addProduct(pdesc, iIsListener);
113  }
114 
115  if (!missingDictionaries.empty()) {
116  std::string context("Calling ProductRegistryHelper::addToRegistry, checking dictionaries for produced types");
117  throwMissingDictionariesException(missingDictionaries, context, producedTypes);
118  }
119  }
120 } // namespace edm
type
Definition: HCALResponse.h:21
void throwMissingDictionariesException(std::vector< std::string > &missingDictionaries, std::string const &context)
std::string const & processName() const
TypeLabelList const & typeLabelList() const
used by the fwk to register the list of products of this module
std::string const & moduleName() const
virtual ~ProductRegistryHelper() noexcept(false)
static void addToRegistry(TypeLabelList::const_iterator const &iBegin, TypeLabelList::const_iterator const &iEnd, ModuleDescription const &iDesc, ProductRegistry &iReg, ProductRegistryHelper *iProd, bool iIsListener=false)
std::string const & moduleLabel() const
constexpr bool isEndTransition(Transition iValue)
Definition: Transition.h:25
virtual bool hasAbilityToProduceInRuns() const
std::vector< TypeLabelItem > TypeLabelList
bool checkDictionary(std::vector< std::string > &missingDictionaries, TypeID const &typeID)
bool checkClassDictionaries(std::vector< std::string > &missingDictionaries, TypeID const &typeID)
virtual bool hasAbilityToProduceInLumis() const
#define noexcept
HLT enums.
ParameterSetID const & parameterSetID() const
bool checkDictionaryOfWrappedType(std::vector< std::string > &missingDictionaries, TypeID const &unwrappedTypeID)
void addProduct(BranchDescription const &productdesc, bool iFromListener=false)
void setIsMergeable(BranchDescription &)
constexpr BranchType convertToBranchType(Transition iValue)
Definition: Transition.h:15
def branchType(schema, name)
Definition: revisionDML.py:114