161 lines
4.6 KiB
C++
161 lines
4.6 KiB
C++
|
//
|
||
|
// Created by bbr on 27.05.22..
|
||
|
//
|
||
|
|
||
|
#include "application.h"
|
||
|
#include "comdel/parser/parse_context.h"
|
||
|
#include "comdel/parser/parser_util.h"
|
||
|
#include "comdel/domain/schema_creator.h"
|
||
|
#include "comdel/domain/comdel_generator.h"
|
||
|
#include "comdel/domain/comdel_validator.h"
|
||
|
|
||
|
std::optional<domain::Library> Application::getLibrary() {
|
||
|
return library;
|
||
|
}
|
||
|
|
||
|
domain::Schema *Application::getSchema() {
|
||
|
return schema;
|
||
|
}
|
||
|
|
||
|
void Application::clear() {
|
||
|
if(schema != nullptr) {
|
||
|
delete schema;
|
||
|
schema = nullptr;
|
||
|
}
|
||
|
library = std::nullopt;
|
||
|
libraryPath = "";
|
||
|
}
|
||
|
|
||
|
bool Application::loadLibrary(std::string& filename, std::ostream &errorOutput) {
|
||
|
clear();
|
||
|
|
||
|
ParseContext parseContext;
|
||
|
auto libraryNode = load_library_from_file(&parseContext, filename.c_str(), errorOutput);
|
||
|
if(libraryNode) {
|
||
|
domain::SchemaCreator generator(validators);
|
||
|
library = generator.loadLibrary(*libraryNode);
|
||
|
|
||
|
for (auto& error : generator.getErrors()) {
|
||
|
parseContext.formatError(error, errorOutput, "ERROR: ");
|
||
|
}
|
||
|
|
||
|
if(library.has_value()) {
|
||
|
libraryPath = filename;
|
||
|
// on library load we create a new schema
|
||
|
schema = new domain::Schema();
|
||
|
} else {
|
||
|
errorOutput<<"Failed creating library model"<<std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
errorOutput<<"Failed parsing library"<<std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool Application::loadSchema(std::string &filename, std::ostream &errorOutput) {
|
||
|
clear();
|
||
|
|
||
|
ParseContext parseContext;
|
||
|
auto schemaNode = load_schema_from_file(&parseContext, filename.c_str(), errorOutput);
|
||
|
|
||
|
if(schemaNode) {
|
||
|
domain::SchemaCreator generator(validators);
|
||
|
library = generator.loadLibrary(*schemaNode->library);
|
||
|
|
||
|
libraryPath = schemaNode->source->asString();
|
||
|
|
||
|
for (auto& error : generator.getErrors()) {
|
||
|
parseContext.formatError(error, errorOutput, "ERROR: ");
|
||
|
}
|
||
|
|
||
|
if(library) {
|
||
|
schema = generator.loadSchema(*schemaNode, *library);
|
||
|
|
||
|
for (auto& error : generator.getErrors()) {
|
||
|
parseContext.formatError(error, errorOutput, "ERROR: ");
|
||
|
}
|
||
|
|
||
|
if(schema == nullptr) {
|
||
|
clear();
|
||
|
return false;
|
||
|
}
|
||
|
} else {
|
||
|
clear();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
errorOutput<<"Failed parsing library"<<std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool Application::generateSchema(std::ostringstream &output) {
|
||
|
if(schema == nullptr) {
|
||
|
return false;
|
||
|
}
|
||
|
domain::generate_schema(libraryPath, schema, output);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
std::vector<domain::ValidationError> Application::validateSchema() {
|
||
|
if(schema == nullptr) {
|
||
|
return std::vector<domain::ValidationError>{domain::ValidationError(domain::Action::ERROR, "No schema loaded")};
|
||
|
}
|
||
|
|
||
|
domain::ComdelValidator validator{validators};
|
||
|
|
||
|
domain::ValidationContext context;
|
||
|
context.instance = nullptr;
|
||
|
context.attribute = nullptr;
|
||
|
context.addressSpaces = {};
|
||
|
|
||
|
for(auto &lib: library->getAddressSpaces()) {
|
||
|
context.addressSpaces.insert(std::make_pair(lib.getName(), lib));
|
||
|
}
|
||
|
auto errors = validator.validateSchema(*schema, context);
|
||
|
|
||
|
auto countValidation = validator.validateInstanceCount(*schema, *library, context);
|
||
|
errors.insert(errors.end(), countValidation.begin(), countValidation.end());
|
||
|
|
||
|
auto nameValidation = validator.validateInstanceNames(*schema, *library, context);
|
||
|
errors.insert(errors.end(), nameValidation.begin(), nameValidation.end());
|
||
|
|
||
|
auto pinValidation = validator.validatePinConnections(*schema, *library, context);
|
||
|
errors.insert(errors.end(), pinValidation.begin(), pinValidation.end());
|
||
|
return errors;
|
||
|
}
|
||
|
|
||
|
std::vector<domain::ValidationError> Application::generateComdel(std::ostringstream &output) {
|
||
|
|
||
|
auto errors = validateSchema();
|
||
|
if(Application::hasErrors(errors)) {
|
||
|
// as long as all validation errors are warning we continue with build
|
||
|
domain::generate_comdel(schema, library.value(), output);
|
||
|
}
|
||
|
return errors;
|
||
|
}
|
||
|
|
||
|
bool Application::hasErrors(std::vector<domain::ValidationError> errors) {
|
||
|
for(auto& err: errors) {
|
||
|
if(err.type == domain::Action::ERROR) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// static instance of application
|
||
|
static Application *application = nullptr;
|
||
|
|
||
|
Application *Application::instance() {
|
||
|
if(application == nullptr) {
|
||
|
application = new Application();
|
||
|
}
|
||
|
return application;
|
||
|
}
|