/* Ousía Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "DomainHandler.hpp" #include #include #include namespace ousia { /* DomainHandler */ void DomainHandler::start(Variant::mapType &args) { Rooted domain = project()->createDomain(args["name"].asString()); domain->setLocation(location()); scope().push(domain); } void DomainHandler::end() { scope().pop(); } /* DomainStructHandler */ void DomainStructHandler::start(Variant::mapType &args) { scope().setFlag(ParserFlag::POST_HEAD, true); Rooted domain = scope().selectOrThrow(); Rooted structuredClass = domain->createStructuredClass( args["name"].asString(), args["cardinality"].asCardinality(), nullptr, args["transparent"].asBool(), args["isRoot"].asBool()); structuredClass->setLocation(location()); const std::string &isa = args["isa"].asString(); if (!isa.empty()) { scope().resolve( isa, structuredClass, logger(), [](Handle superclass, Handle structuredClass, Logger &logger) { if (superclass != nullptr) { structuredClass.cast()->setSuperclass( superclass.cast(), logger); } }); } scope().push(structuredClass); } void DomainStructHandler::end() { scope().pop(); } /* DomainAnnotationHandler */ void DomainAnnotationHandler::start(Variant::mapType &args) { scope().setFlag(ParserFlag::POST_HEAD, true); Rooted domain = scope().selectOrThrow(); Rooted annotationClass = domain->createAnnotationClass(args["name"].asString()); annotationClass->setLocation(location()); scope().push(annotationClass); } void DomainAnnotationHandler::end() { scope().pop(); } /* DomainAttributesHandler */ void DomainAttributesHandler::start(Variant::mapType &args) { // Fetch the current typesystem and create the struct node Rooted parent = scope().selectOrThrow(); Rooted attrDesc = parent->getAttributesDescriptor(); attrDesc->setLocation(location()); scope().push(attrDesc); } void DomainAttributesHandler::end() { scope().pop(); } /* DomainFieldHandler */ void DomainFieldHandler::start(Variant::mapType &args) { FieldDescriptor::FieldType type; if (args["isSubtree"].asBool()) { type = FieldDescriptor::FieldType::SUBTREE; } else { type = FieldDescriptor::FieldType::TREE; } Rooted parent = scope().selectOrThrow(); Rooted field = parent->createFieldDescriptor( logger(), type, args["name"].asString(), args["optional"].asBool()); field->setLocation(location()); scope().push(field); } void DomainFieldHandler::end() { scope().pop(); } /* DomainFieldRefHandler */ void DomainFieldRefHandler::start(Variant::mapType &args) { Rooted parent = scope().selectOrThrow(); const std::string &name = args["ref"].asString(); scope().resolveFieldDescriptor( name, parent, logger(), [](Handle field, Handle parent, Logger &logger) { if (field != nullptr) { parent.cast()->addFieldDescriptor( field.cast(), logger); } }); } void DomainFieldRefHandler::end() {} /* DomainPrimitiveHandler */ void DomainPrimitiveHandler::start(Variant::mapType &args) { Rooted parent = scope().selectOrThrow(); FieldDescriptor::FieldType fieldType; if (args["isSubtree"].asBool()) { fieldType = FieldDescriptor::FieldType::SUBTREE; } else { fieldType = FieldDescriptor::FieldType::TREE; } Rooted field = parent->createPrimitiveFieldDescriptor( nullptr, logger(), fieldType, args["name"].asString(), args["optional"].asBool()); field->setLocation(location()); const std::string &type = args["type"].asString(); scope().resolve(type, field, logger(), [](Handle type, Handle field, Logger &logger) { if (type != nullptr) { field.cast()->setPrimitiveType(type.cast()); } }); scope().push(field); } void DomainPrimitiveHandler::end() { scope().pop(); } /* DomainChildHandler */ void DomainChildHandler::start(Variant::mapType &args) { Rooted field = scope().selectOrThrow(); const std::string &ref = args["ref"].asString(); scope().resolve( ref, field, logger(), [](Handle child, Handle field, Logger &logger) { if (child != nullptr) { field.cast()->addChild( child.cast()); } }); } void DomainChildHandler::end() {} /* DomainParentHandler */ void DomainParentHandler::start(Variant::mapType &args) { Rooted strct = scope().selectOrThrow(); Rooted parent{ new DomainParent(strct->getManager(), args["ref"].asString(), strct)}; parent->setLocation(location()); scope().push(parent); } void DomainParentHandler::end() { scope().pop(); } /* DomainParentFieldHandler */ void DomainParentFieldHandler::start(Variant::mapType &args) { Rooted parentNameNode = scope().selectOrThrow(); FieldDescriptor::FieldType type; if (args["isSubtree"].asBool()) { type = FieldDescriptor::FieldType::SUBTREE; } else { type = FieldDescriptor::FieldType::TREE; } const std::string &name = args["name"].asString(); const bool optional = args["optional"].asBool(); Rooted strct = parentNameNode->getParent().cast(); // resolve the parent, create the declared field and add the declared // StructuredClass as child to it. scope().resolve( parentNameNode->getName(), strct, logger(), [type, name, optional](Handle parent, Handle strct, Logger &logger) { if (parent != nullptr) { Rooted field = parent.cast()->createFieldDescriptor( logger, type, name, optional); field->addChild(strct.cast()); } }); } void DomainParentFieldHandler::end() {} /* DomainParentFieldRefHandler */ void DomainParentFieldRefHandler::start(Variant::mapType &args) { Rooted parentNameNode = scope().selectOrThrow(); const std::string &name = args["ref"].asString(); Rooted strct = parentNameNode->getParent().cast(); auto loc = location(); // resolve the parent, get the referenced field and add the declared // StructuredClass as child to it. scope().resolve( parentNameNode->getName(), strct, logger(), [name, loc](Handle parent, Handle strct, Logger &logger) { if (parent != nullptr) { Rooted field = parent.cast()->getFieldDescriptor(name); if (field == nullptr) { logger.error( std::string("Could not find referenced field ") + name, loc); return; } field->addChild(strct.cast()); } }); } void DomainParentFieldRefHandler::end() {} namespace RttiTypes { const Rtti DomainParent = RttiBuilder("DomainParent").parent(&Node); } }