19 #include <momemta/ModuleDefBuilder.h> 21 #include <momemta/Logging.h> 23 #include <ModuleDefUtils.h> 24 #include <strings/Scanner.h> 27 namespace registration {
31 class invalid_name:
public std::runtime_error {
32 using std::runtime_error::runtime_error;
35 class invalid_type:
public std::runtime_error {
36 using std::runtime_error::runtime_error;
39 class missing_attribute:
public std::runtime_error {
40 using std::runtime_error::runtime_error;
52 void finalizeInputOrOutput(StringPiece spec,
bool is_output, ModuleRegistrationData& data) {
53 using namespace strings;
60 def.optional = spec.Consume(
"?");
62 def.many = spec.Consume(
"*");
73 .GetResult(&spec, &out)) {
78 auto nested_attribute = out.ToString();
81 auto attr = momemta::findAttr(nested_attribute, data.module_def);
83 std::string error =
"Input definition for module " + data.module_def.name +
" references a non-existing " 84 "attribute: " + nested_attribute;
86 throw missing_attribute(error);
88 def.nested_attributes.push_back(*attr);
96 .Any(Scanner::LETTER_DIGIT_UNDERSCORE)
99 .GetResult(&spec, &out)) {
100 throw invalid_name(std::string(
"Invalid ") +
101 ((is_output) ?
"output" :
"input") +
102 " name format (<name>:) for module " + data.module_def.name);
105 def.name = out.ToString();
109 bool has_default = spec.Consume(
"=");
112 .Any(Scanner::LETTER_DIGIT_UNDERSCORE_COLON)
115 .GetResult(&spec, &out);
117 def.default_value = out.ToString();
123 data.module_def.outputs.emplace_back(def);
125 data.module_def.inputs.emplace_back(def);
129 void finalizeAttr(StringPiece spec, ModuleRegistrationData& data) {
130 using namespace strings;
135 def.global = spec.Consume(
"^");
138 def.optional = spec.Consume(
"?");
144 .One(Scanner::LETTER)
145 .Any(Scanner::LETTER_DIGIT_UNDERSCORE)
150 .GetResult(&spec, &out)) {
151 throw invalid_name(
"Invalid attribute name format (<name>:) for module " + data.module_def.name);
154 def.name = out.ToString();
157 bool is_list = Scanner(spec)
166 .Any(Scanner::LOWERLETTER)
169 .GetResult(&spec, &out)) {
170 throw invalid_type(
"Invalid type format for attribute " + def.name +
" for module " + data.module_def.name);
176 def.type =
"list(" + out.ToString() +
")";
178 def.type = out.ToString();
186 if (spec.Consume(
"=")) {
188 .Any(Scanner::LETTER_DIGIT_DASH_DOT_SLASH_UNDERSCORE)
191 .GetResult(&spec, &out);
192 def.default_value = out.ToString();
196 data.module_def.attributes.emplace_back(def);
201 ModuleDefBuilder::ModuleDefBuilder(
const std::string& name) {
202 reg_data.module_def.name = name;
204 if (name.length() > 1 && name[0] ==
'_')
205 reg_data.module_def.internal =
true;
209 inputs.emplace_back(spec);
215 inputs.emplace_back(
"?" + spec);
221 inputs.emplace_back(
"*" + spec);
227 inputs.emplace_back(
"?*" + spec);
232 outputs.emplace_back(spec);
237 attrs.emplace_back(spec);
243 attrs.emplace_back(
"^" + spec);
249 attrs.emplace_back(
"?" + spec);
254 reg_data.module_def.sticky =
true;
258 std::string ModuleDefBuilder::name()
const {
259 return reg_data.module_def.name;
264 auto data = reg_data;
266 for (
const auto& spec: attrs) {
267 finalizeAttr(spec, data);
270 for (
const auto& spec: inputs) {
271 finalizeInputOrOutput(spec,
false, data);
274 for (
const auto& spec: outputs) {
275 finalizeInputOrOutput(spec,
true, data);
ModuleDefBuilder & Sticky()
Flag this module as sticky.
ModuleDefBuilder & GlobalAttr(const std::string &spec)
Adds a global attribute to the module definition (and returns *this).
ModuleDefBuilder & OptionalInputs(const std::string &spec)
Adds optional inputs to the module definition (and returns *this).
ModuleDefBuilder & Inputs(const std::string &spec)
Adds inputs to the module definition (and returns *this).
ModuleDefBuilder & OptionalInput(const std::string &spec)
Adds an optional input to the module definition (and returns *this).
ModuleDefBuilder & Input(const std::string &spec)
Adds an input to the module definition (and returns *this).
ModuleDefBuilder & Attr(const std::string &spec)
Adds an attribute to the module definition (and returns *this).
ModuleDefBuilder & OptionalAttr(const std::string &spec)
Adds an optional attribute to the module definition (and returns *this).