File indexing completed on 2025-01-31 02:19:24
0001
0002
0003
0004
0005 #include "FWCore/Framework/interface/ProductRegistryHelper.h"
0006 #include "DataFormats/Common/interface/setIsMergeable.h"
0007 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0008 #include "DataFormats/Provenance/interface/ProductDescription.h"
0009 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0010 #include "FWCore/Reflection/interface/DictionaryTools.h"
0011 #include "FWCore/Utilities/interface/EDMException.h"
0012 #include "FWCore/Reflection/interface/TypeWithDict.h"
0013
0014 #include <vector>
0015 #include <typeindex>
0016
0017 namespace edm {
0018 ProductRegistryHelper::~ProductRegistryHelper() noexcept(false) {}
0019
0020 ProductRegistryHelper::TypeLabelList const& ProductRegistryHelper::typeLabelList() const { return typeLabelList_; }
0021
0022 namespace {
0023 void throwProducesWithoutAbility(const char* transitionName, std::string const& productTypeName) {
0024 throw edm::Exception(edm::errors::LogicError)
0025 << "Module declares it can produce a product of type \'" << productTypeName << "\'\nin a " << transitionName
0026 << ", but does not have the ability to produce in " << transitionName << "s.\n"
0027 << "You must add a template parameter of type " << transitionName << "Producer\n"
0028 << "or " << transitionName << "Producer to the EDProducer or EDFilter base class\n"
0029 << "of the module. Or you could remove the call to the function \'produces\'\n"
0030 << "(Note legacy modules are not ever allowed to produce in Runs or Lumis)\n";
0031 }
0032 }
0033
0034 void ProductRegistryHelper::addToRegistry(TypeLabelList::const_iterator const& iBegin,
0035 TypeLabelList::const_iterator const& iEnd,
0036 ModuleDescription const& iDesc,
0037 ProductRegistry& iReg,
0038 ProductRegistryHelper* iProd,
0039 bool iIsListener) {
0040 std::vector<std::string> missingDictionaries;
0041 std::vector<std::string> producedTypes;
0042 std::set<std::tuple<BranchType, std::type_index, std::string>> registeredProducts;
0043
0044 for (TypeLabelList::const_iterator p = iBegin; p != iEnd; ++p) {
0045 if (p->transition_ == Transition::BeginRun && not iProd->hasAbilityToProduceInBeginRuns()) {
0046 throwProducesWithoutAbility("BeginRun", p->typeID_.userClassName());
0047 } else if (p->transition_ == Transition::EndRun && not iProd->hasAbilityToProduceInEndRuns()) {
0048 throwProducesWithoutAbility("EndRun", p->typeID_.userClassName());
0049 } else if (p->transition_ == Transition::BeginLuminosityBlock && not iProd->hasAbilityToProduceInBeginLumis()) {
0050 throwProducesWithoutAbility("BeginLuminosityBlock", p->typeID_.userClassName());
0051 } else if (p->transition_ == Transition::EndLuminosityBlock && not iProd->hasAbilityToProduceInEndLumis()) {
0052 throwProducesWithoutAbility("EndLuminosityBlock", p->typeID_.userClassName());
0053 } else if (p->transition_ == Transition::BeginProcessBlock &&
0054 not iProd->hasAbilityToProduceInBeginProcessBlocks()) {
0055 throwProducesWithoutAbility("BeginProcessBlock", p->typeID_.userClassName());
0056 } else if (p->transition_ == Transition::EndProcessBlock && not iProd->hasAbilityToProduceInEndProcessBlocks()) {
0057 throwProducesWithoutAbility("EndProcessBlock", p->typeID_.userClassName());
0058 }
0059 if (!checkDictionary(missingDictionaries, p->typeID_)) {
0060 checkDictionaryOfWrappedType(missingDictionaries, p->typeID_);
0061 producedTypes.emplace_back(p->typeID_.className());
0062 continue;
0063 }
0064 auto branchType = convertToBranchType(p->transition_);
0065 if (branchType != InEvent) {
0066 std::tuple<BranchType, std::type_index, std::string> entry{
0067 branchType, p->typeID_.typeInfo(), p->productInstanceName_};
0068 if (registeredProducts.end() != registeredProducts.find(entry)) {
0069
0070
0071 continue;
0072 } else {
0073 registeredProducts.insert(entry);
0074 }
0075 }
0076
0077 TypeWithDict type(p->typeID_.typeInfo());
0078 ProductDescription pdesc(branchType,
0079 iDesc.moduleLabel(),
0080 iDesc.processName(),
0081 p->typeID_.userClassName(),
0082 p->typeID_.friendlyClassName(),
0083 p->productInstanceName_,
0084 type,
0085 true,
0086 isEndTransition(p->transition_));
0087 if (p->aliasType_ == TypeLabelItem::AliasType::kSwitchAlias) {
0088 if (p->branchAlias_.empty()) {
0089 throw edm::Exception(edm::errors::LogicError)
0090 << "Branch alias type has been set to SwitchAlias, but the alias content is empty.\n"
0091 << "Please report this error to the FWCore developers";
0092 }
0093 pdesc.setSwitchAliasModuleLabel(p->branchAlias_);
0094 }
0095 if (p->isTransform_) {
0096 pdesc.setOnDemand(true);
0097 pdesc.setIsTransform(true);
0098 }
0099 setIsMergeable(pdesc);
0100
0101 if (pdesc.transient()) {
0102 if (!checkDictionary(missingDictionaries, pdesc.wrappedName(), pdesc.wrappedType())) {
0103
0104
0105
0106 producedTypes.emplace_back(pdesc.className());
0107 continue;
0108 }
0109 } else {
0110
0111 if (!checkClassDictionaries(missingDictionaries, pdesc.wrappedName(), pdesc.wrappedType())) {
0112 producedTypes.emplace_back(pdesc.className());
0113 continue;
0114 }
0115 }
0116 if (!p->branchAlias_.empty())
0117 pdesc.insertBranchAlias(p->branchAlias_);
0118 iReg.addProduct(pdesc, iIsListener);
0119 }
0120
0121 if (!missingDictionaries.empty()) {
0122 std::string context("Calling ProductRegistryHelper::addToRegistry, checking dictionaries for produced types");
0123 throwMissingDictionariesException(missingDictionaries, context, producedTypes);
0124 }
0125 }
0126 }