diff options
Diffstat (limited to 'tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc')
-rw-r--r-- | tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc b/tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc new file mode 100644 index 0000000000..49bd758b6e --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc @@ -0,0 +1,212 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/cpp_interface_code_generator.h" + +#include "cppgen/generator_preferences.h" +#include "cppgen/handler_interface.h" +#include "cppgen/message_factory_function.h" +#include "cppgen/message_interface.h" +#include "cppgen/module_manager.h" +#include "model/interface.h" +#include "model/type_registry.h" + +namespace codegen { + +CppInterfaceCodeGenerator::CppInterfaceCodeGenerator( + const Interface* interface, + const TypePreferences* preferences, + ModuleManager* module_manager) + : interface_(interface), + preferences_(preferences), + module_manager_(module_manager), + declaration_generator_(preferences, module_manager_), + definition_generator_(preferences, module_manager_) { +} + +CppInterfaceCodeGenerator::~CppInterfaceCodeGenerator() { +} + +void CppInterfaceCodeGenerator::GenerateCode() { + GenerateEnums(); + GenerateTypedefs(); + GenerateStructs(); + bool type_only_interface = + interface_->function_id_enum()->constants().empty(); + if (!type_only_interface) { + GenerateFunctions(); + GenerateResponses(); + GenerateNotifications(); + GenerateHandlerInterfaces(); + GenerateMessageBaseClasses(); + GenerateMessageFactories(); + } +} + +void CppInterfaceCodeGenerator::GenerateEnums() { + const Interface::EnumList& enums = interface_->enums(); + for (Interface::EnumList::const_iterator i = enums.begin(), end = enums.end(); + i != end; ++i) { + const Enum* e = *i; + declaration_generator_.GenerateCodeForEnum(e); + definition_generator_.GenerateCodeForEnum(e); + } + + const Enum* func_id_enum = interface_->function_id_enum(); + // Not all interfaces declare functions, avoid empty enum generation + if (!func_id_enum->constants().empty()) { + declaration_generator_.GenerateCodeForEnum(func_id_enum); + definition_generator_.GenerateCodeForEnum(func_id_enum); + } +} + +void CppInterfaceCodeGenerator::GenerateStructs() { + const Interface::StructList& structs = interface_->structs(); + for (Interface::StructList::const_iterator i = structs.begin(), end = structs + .end(); i != end; ++i) { + const Struct* s = *i; + declaration_generator_.GenerateCodeForStruct(s); + definition_generator_.GenerateCodeForStruct(s); + } +} + +void CppInterfaceCodeGenerator::GenerateTypedefs() { + const Interface::TypedefList& typedefs = interface_->typedefs(); + for (Interface::TypedefList::const_iterator i = typedefs.begin(), end = + typedefs.end(); i != end; ++i) { + const Typedef* tdef = *i; + declaration_generator_.GenerateCodeForTypedef(tdef); + } +} + +void CppInterfaceCodeGenerator::GenerateFunctions() { + const Interface::FunctionsList& functions = interface_->functions(); + for (Interface::FunctionsList::const_iterator i = functions.begin(), end = + functions.end(); i != end; ++i) { + const Function& function = *i; + declaration_generator_.GenerateCodeForFunction(function); + definition_generator_.GenerateCodeForFunction(function); + } +} + +void CppInterfaceCodeGenerator::GenerateResponses() { + const Interface::ResponseList& responses = interface_->generic_responses(); + for (Interface::ResponseList::const_iterator i = responses.begin(), end = + responses.end(); i != end; ++i) { + const Response& response = **i; + declaration_generator_.GenerateCodeForResponse(response); + definition_generator_.GenerateCodeForResponse(response); + } +} + +void CppInterfaceCodeGenerator::GenerateNotifications() { + const Interface::NotificationList& notifications = + interface_->notifications(); + for (Interface::NotificationList::const_iterator i = notifications.begin(), + end = notifications.end(); i != end; ++i) { + const Notification& notification = **i; + declaration_generator_.GenerateCodeForNotification(notification); + definition_generator_.GenerateCodeForNotification(notification); + } +} + +void CppInterfaceCodeGenerator::GenerateHandlerInterfaces() { + CppFile& handler_header = module_manager_->HeaderForInterface(); + CppFile& handler_source = module_manager_->SourceForInterface(); + HandlerInterface notif_handler( + FunctionMessage::kNotification, interface_, &handler_header); + notif_handler.Declare(&handler_header.notifications_ns().os()); + notif_handler.Define(&handler_source.notifications_ns().os()); + + HandlerInterface req_handler( + FunctionMessage::kRequest, interface_, &handler_header); + req_handler.Declare(&handler_header.requests_ns().os()); + req_handler.Define(&handler_source.requests_ns().os()); + + HandlerInterface resp_handler( + FunctionMessage::kResponse, interface_, &handler_header); + resp_handler.Declare(&handler_header.responses_ns().os()); + resp_handler.Define(&handler_source.responses_ns().os()); +} + +void CppInterfaceCodeGenerator::GenerateMessageBaseClasses() { + CppFile& message_base_header = module_manager_->HeaderForInterface(); + CppFile& message_base_source = module_manager_->SourceForInterface(); + MessageInterface notif_message(interface_, FunctionMessage::kNotification); + notif_message.Declare(&message_base_header.notifications_ns().os()); + notif_message.Define(&message_base_source.notifications_ns().os()); + + MessageInterface request_message(interface_, FunctionMessage::kRequest); + request_message.Declare(&message_base_header.requests_ns().os()); + request_message.Define(&message_base_source.requests_ns().os()); + + MessageInterface response_message(interface_, FunctionMessage::kResponse); + response_message.Declare(&message_base_header.responses_ns().os()); + response_message.Define(&message_base_source.responses_ns().os()); +} + +void CppInterfaceCodeGenerator::GenerateMessageFactories() { + CppFile& factories_header = module_manager_->HeaderForInterface(); + CppFile& factories_source = module_manager_->SourceForInterface(); + + MessageFactoryFunction::SerializationType ser_types[2]; + size_t ser_types_count = 0; + if (preferences_->generate_json) { + ser_types[ser_types_count++] = MessageFactoryFunction::kJson; + } + if (preferences_->generate_dbus) { + ser_types[ser_types_count++] = MessageFactoryFunction::kDbus; + } + + for (size_t i = 0; i < ser_types_count; ++i) { + MessageFactoryFunction request_factory(interface_, + ser_types[i], + FunctionMessage::kRequest); + request_factory.Declare(&factories_header.requests_ns().os(), true); + request_factory.Define(&factories_source.requests_ns().os(), true); + MessageFactoryFunction response_factory(interface_, + ser_types[i], + FunctionMessage::kResponse); + response_factory.Declare(&factories_header.responses_ns().os(), true); + response_factory.Define(&factories_source.responses_ns().os(), true); + MessageFactoryFunction notification_factory( + interface_, + ser_types[i], + FunctionMessage::kNotification); + notification_factory.Declare(&factories_header.notifications_ns().os(), + true); + notification_factory.Define(&factories_source.notifications_ns().os(), true); + } + +} + +} // namespace codegen |