in source/ModelGeneration.cpp [97:219]
ModelGeneratorResult ModelGeneration::run(Context& context) {
const auto& options = *context.options;
const auto& generated_models_directory = options.generated_models_directory();
if (generated_models_directory) {
LOG(2,
"Removing existing model generators under `{}`...",
*generated_models_directory);
for (auto& file :
boost::filesystem::directory_iterator(*generated_models_directory)) {
const auto& file_path = file.path();
if (boost::filesystem::is_regular_file(file_path) &&
boost::ends_with(file_path.filename().string(), ".json")) {
boost::filesystem::remove(file_path);
}
}
}
auto builtin_generators = make_model_generators(context);
std::vector<std::unique_ptr<ModelGenerator>> model_generators;
const auto& configuration_entries = options.model_generators_configuration();
std::vector<std::string> nonexistent_model_generators;
for (const auto& entry : configuration_entries) {
const std::string& name = entry.name();
LOG(2, "Found model generator: `{}`", name);
auto iterator = builtin_generators.find(name);
if (iterator == builtin_generators.end()) {
bool generator_exists = std::any_of(
model_generators.begin(),
model_generators.end(),
[&](const auto& generator) { return generator->name() == name; });
if (!generator_exists) {
nonexistent_model_generators.push_back(name);
}
} else {
model_generators.push_back(std::move(iterator->second));
builtin_generators.erase(iterator);
}
}
if (!nonexistent_model_generators.empty()) {
throw std::invalid_argument(fmt::format(
"Model generator(s) {} either do not exist or couldn't be parsed.",
boost::algorithm::join(nonexistent_model_generators, ", ")));
}
std::vector<Model> generated_models;
std::vector<FieldModel> generated_field_models;
std::size_t iteration = 0;
LOG(1,
"Building method mappings for model generation over {} methods",
context.methods->size());
Timer method_mapping_timer;
std::unique_ptr<MethodMappings> method_mappings =
std::make_unique<MethodMappings>(*context.methods);
LOG(1,
"Generated method mappings in {:.2f}s",
method_mapping_timer.duration_in_seconds());
for (const auto& model_generator : model_generators) {
Timer generator_timer;
LOG(1,
"Running model generator `{}` ({}/{})",
model_generator->name(),
++iteration,
model_generators.size());
auto [models, field_models] = model_generator->run_optimized(
*context.methods, *method_mappings, *context.fields);
// Remove models for the `null` method
models.erase(
std::remove_if(
models.begin(),
models.end(),
[](const Model& model) { return !model.method(); }),
models.end());
field_models.erase(
std::remove_if(
field_models.begin(),
field_models.end(),
[](const FieldModel& field_model) { return !field_model.field(); }),
field_models.end());
generated_models.insert(
generated_models.end(), models.begin(), models.end());
generated_field_models.insert(
generated_field_models.end(), field_models.begin(), field_models.end());
LOG(2,
"Generated {} models in {:.2f}s.",
models.size(),
generator_timer.duration_in_seconds());
if (generated_models_directory) {
// Persist models to file.
Timer generator_output_timer;
LOG(2,
"Writing generated models to `{}`...",
*generated_models_directory);
// Merge models
auto registry = Registry(context, models, field_models);
JsonValidation::write_json_file(
*generated_models_directory + "/" + model_generator->name() + ".json",
registry.models_to_json());
LOG(2,
"Wrote {} generated models to `{}` in {:.2f}s.",
registry.models_size(),
*generated_models_directory,
generator_output_timer.duration_in_seconds());
}
}
return {
/* method_models */ generated_models,
/* field_models */ generated_field_models};
}