From 7bc7dc24301d852210cb974e368e40adfb245ffd Mon Sep 17 00:00:00 2001
From: Aleksandar Brakmic
<13668697+brakmic-aleksandar@users.noreply.github.com>
Date: Thu, 29 Apr 2021 14:46:54 +0200
Subject: [PATCH] Initial commit
Co-authored-by: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com>
---
.gitignore | 53 +++
LICENSE | 202 +++++++++++
README.md | 13 +
rosidl_adapter_proto/CMakeLists.txt | 37 ++
rosidl_adapter_proto/bin/rosidl_adapter_proto | 87 +++++
.../cmake/rosidl_adapt_proto_interfaces.cmake | 96 +++++
.../rosidl_adapter_proto-extras.cmake.in | 52 +++
rosidl_adapter_proto/package.xml | 23 ++
rosidl_adapter_proto/resource/action.proto.em | 63 ++++
rosidl_adapter_proto/resource/idl.proto.em | 127 +++++++
rosidl_adapter_proto/resource/msg.proto.em | 143 ++++++++
...idl_adapter_proto__visibility_control.h.in | 42 +++
rosidl_adapter_proto/resource/srv.proto.em | 60 ++++
.../rosidl_adapter_proto/__init__.py | 114 ++++++
rosidl_typesupport_protobuf/CHANGELOG.rst | 3 +
rosidl_typesupport_protobuf/CMakeLists.txt | 36 ++
.../cmake/discover-ros-distro-extras.cmake | 46 +++
.../message_type_support.hpp | 39 ++
.../message_type_support_decl.hpp | 35 ++
.../proto_descriptor_helper.hpp | 101 ++++++
.../rosidl_generator_c_pkg_adapter.hpp | 153 ++++++++
.../service_type_support.hpp | 38 ++
.../service_type_support_decl.hpp | 39 ++
.../visibility_control.h | 57 +++
rosidl_typesupport_protobuf/package.xml | 16 +
.../rosidl_typesupport_protobuf/__init__.py | 130 +++++++
rosidl_typesupport_protobuf_c/CMakeLists.txt | 130 +++++++
.../bin/rosidl_typesupport_protobuf_c | 54 +++
...idl_typesupport_protobuf_c-extras.cmake.in | 29 ++
...pport_protobuf_c_generate_interfaces.cmake | 185 ++++++++++
.../identifier.hpp | 30 ++
.../to_ros_c_string.hpp | 33 ++
.../wstring_conversion.hpp | 36 ++
rosidl_typesupport_protobuf_c/package.xml | 35 ++
.../idl__rosidl_typesupport_protobuf_c.hpp.em | 92 +++++
.../resource/idl__type_support.cpp.em | 121 +++++++
.../msg__rosidl_typesupport_protobuf_c.hpp.em | 85 +++++
.../resource/msg__type_support.cpp.em | 338 ++++++++++++++++++
...upport_protobuf_c__visibility_control.h.in | 42 +++
.../srv__rosidl_typesupport_protobuf_c.hpp.em | 49 +++
.../resource/srv__type_support.cpp.em | 116 ++++++
.../resource/tmpl_forward_declarations.em | 74 ++++
.../resource/tmpl_include_directories.em | 47 +++
.../rosidl_typesupport_protobuf_c/__init__.py | 26 ++
.../src/identifier.cpp | 29 ++
.../src/to_ros_c_string.cpp | 32 ++
.../src/wstring_conversion.cpp | 46 +++
.../CMakeLists.txt | 107 ++++++
.../bin/rosidl_typesupport_protobuf_cpp | 49 +++
...l_typesupport_protobuf_cpp-extras.cmake.in | 32 ++
...ort_protobuf_cpp_generate_interfaces.cmake | 203 +++++++++++
.../identifier.hpp | 30 ++
.../wstring_conversion.hpp | 35 ++
rosidl_typesupport_protobuf_cpp/package.xml | 34 ++
...dl__rosidl_typesupport_protobuf_cpp.hpp.em | 92 +++++
.../resource/idl__type_support.cpp.em | 118 ++++++
...sg__rosidl_typesupport_protobuf_cpp.hpp.em | 83 +++++
.../resource/msg__type_support.cpp.em | 239 +++++++++++++
...port_protobuf_cpp__visibility_control.h.in | 42 +++
...rv__rosidl_typesupport_protobuf_cpp.hpp.em | 47 +++
.../resource/srv__type_support.cpp.em | 115 ++++++
.../resource/tmpl_forward_declarations.em | 73 ++++
.../resource/tmpl_include_directories.em | 47 +++
.../__init__.py | 29 ++
.../src/identifier.cpp | 28 ++
.../src/wstring_conversion.cpp | 42 +++
66 files changed, 4879 insertions(+)
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 README.md
create mode 100644 rosidl_adapter_proto/CMakeLists.txt
create mode 100644 rosidl_adapter_proto/bin/rosidl_adapter_proto
create mode 100644 rosidl_adapter_proto/cmake/rosidl_adapt_proto_interfaces.cmake
create mode 100644 rosidl_adapter_proto/cmake/rosidl_adapter_proto-extras.cmake.in
create mode 100644 rosidl_adapter_proto/package.xml
create mode 100644 rosidl_adapter_proto/resource/action.proto.em
create mode 100644 rosidl_adapter_proto/resource/idl.proto.em
create mode 100644 rosidl_adapter_proto/resource/msg.proto.em
create mode 100644 rosidl_adapter_proto/resource/rosidl_adapter_proto__visibility_control.h.in
create mode 100644 rosidl_adapter_proto/resource/srv.proto.em
create mode 100644 rosidl_adapter_proto/rosidl_adapter_proto/__init__.py
create mode 100644 rosidl_typesupport_protobuf/CHANGELOG.rst
create mode 100644 rosidl_typesupport_protobuf/CMakeLists.txt
create mode 100644 rosidl_typesupport_protobuf/cmake/discover-ros-distro-extras.cmake
create mode 100644 rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support.hpp
create mode 100644 rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support_decl.hpp
create mode 100644 rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/proto_descriptor_helper.hpp
create mode 100644 rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp
create mode 100644 rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support.hpp
create mode 100644 rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support_decl.hpp
create mode 100644 rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/visibility_control.h
create mode 100644 rosidl_typesupport_protobuf/package.xml
create mode 100644 rosidl_typesupport_protobuf/rosidl_typesupport_protobuf/__init__.py
create mode 100644 rosidl_typesupport_protobuf_c/CMakeLists.txt
create mode 100644 rosidl_typesupport_protobuf_c/bin/rosidl_typesupport_protobuf_c
create mode 100644 rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c-extras.cmake.in
create mode 100644 rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c_generate_interfaces.cmake
create mode 100644 rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/identifier.hpp
create mode 100644 rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/to_ros_c_string.hpp
create mode 100644 rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/wstring_conversion.hpp
create mode 100644 rosidl_typesupport_protobuf_c/package.xml
create mode 100644 rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em
create mode 100644 rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em
create mode 100644 rosidl_typesupport_protobuf_c/resource/msg__rosidl_typesupport_protobuf_c.hpp.em
create mode 100644 rosidl_typesupport_protobuf_c/resource/msg__type_support.cpp.em
create mode 100644 rosidl_typesupport_protobuf_c/resource/rosidl_typesupport_protobuf_c__visibility_control.h.in
create mode 100644 rosidl_typesupport_protobuf_c/resource/srv__rosidl_typesupport_protobuf_c.hpp.em
create mode 100644 rosidl_typesupport_protobuf_c/resource/srv__type_support.cpp.em
create mode 100644 rosidl_typesupport_protobuf_c/resource/tmpl_forward_declarations.em
create mode 100644 rosidl_typesupport_protobuf_c/resource/tmpl_include_directories.em
create mode 100644 rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/__init__.py
create mode 100644 rosidl_typesupport_protobuf_c/src/identifier.cpp
create mode 100644 rosidl_typesupport_protobuf_c/src/to_ros_c_string.cpp
create mode 100644 rosidl_typesupport_protobuf_c/src/wstring_conversion.cpp
create mode 100644 rosidl_typesupport_protobuf_cpp/CMakeLists.txt
create mode 100644 rosidl_typesupport_protobuf_cpp/bin/rosidl_typesupport_protobuf_cpp
create mode 100644 rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in
create mode 100644 rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp_generate_interfaces.cmake
create mode 100644 rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/identifier.hpp
create mode 100644 rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp
create mode 100644 rosidl_typesupport_protobuf_cpp/package.xml
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/msg__rosidl_typesupport_protobuf_cpp.hpp.em
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/msg__type_support.cpp.em
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/rosidl_typesupport_protobuf_cpp__visibility_control.h.in
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/srv__rosidl_typesupport_protobuf_cpp.hpp.em
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/srv__type_support.cpp.em
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/tmpl_forward_declarations.em
create mode 100644 rosidl_typesupport_protobuf_cpp/resource/tmpl_include_directories.em
create mode 100644 rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py
create mode 100644 rosidl_typesupport_protobuf_cpp/src/identifier.cpp
create mode 100644 rosidl_typesupport_protobuf_cpp/src/wstring_conversion.cpp
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7b091f1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,53 @@
+devel/
+logs/
+build/
+lib/
+msg_gen/
+srv_gen/
+msg/*Action.msg
+msg/*ActionFeedback.msg
+msg/*ActionGoal.msg
+msg/*ActionResult.msg
+msg/*Feedback.msg
+msg/*Goal.msg
+msg/*Result.msg
+msg/_*.py
+build_isolated/
+devel_isolated/
+
+# Generated by dynamic reconfigure
+*.cfgc
+/cfg/cpp/
+/cfg/*.py
+
+# Ignore generated docs
+*.dox
+*.wikidoc
+
+# eclipse stuff
+.project
+.cproject
+
+# qcreator stuff
+CMakeLists.txt.user
+
+srv/_*.py
+*.pcd
+*.pyc
+qtcreator-*
+*.user
+
+/planning/cfg
+/planning/docs
+/planning/src
+
+*~
+
+# vs-code stuff
+.vscode
+
+# Emacs
+.#*
+
+# Catkin custom files
+CATKIN_IGNORE
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f9f6c64
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright (C) 2019 - 2020 Continental Corporation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5402bd9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# Protobuf based rosidl typesupport
+
+Middleware agnostic ros2 static typesupport which uses Protobuf for serialization/deserialization.
+
+## Build instructions
+
+* Clone latest release of this repository into your [ROS2 workspace](https://index.ros.org/doc/ros2/Tutorials/Workspace/Creating-A-Workspace/)
+* Source ROS2 `source /path/to/your/ros/distro/folder/setup.bash`
+* Run `colcon build` from your workspace folder
+* Setup your workspace `source /path/to/your/workspace/install/setup.bash`
+
+**Note**: Typesupport must be built and sourced before any project messages are built.
+**Note 2**: If you are using messages that are not being built by project (ex. builtin_interfaces) they need to be rebuilt and sourced in your workspace.
\ No newline at end of file
diff --git a/rosidl_adapter_proto/CMakeLists.txt b/rosidl_adapter_proto/CMakeLists.txt
new file mode 100644
index 0000000..8c50488
--- /dev/null
+++ b/rosidl_adapter_proto/CMakeLists.txt
@@ -0,0 +1,37 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+cmake_minimum_required(VERSION 3.12)
+
+project(rosidl_adapter_proto)
+
+find_package(ament_cmake REQUIRED)
+find_package(ament_cmake_python REQUIRED)
+
+ament_python_install_package(${PROJECT_NAME})
+
+ament_package(CONFIG_EXTRAS "cmake/rosidl_adapter_proto-extras.cmake.in")
+
+install(
+ PROGRAMS bin/rosidl_adapter_proto
+ DESTINATION lib/rosidl_adapter_proto
+)
+
+install(
+ DIRECTORY cmake resource
+ DESTINATION share/${PROJECT_NAME}
+)
\ No newline at end of file
diff --git a/rosidl_adapter_proto/bin/rosidl_adapter_proto b/rosidl_adapter_proto/bin/rosidl_adapter_proto
new file mode 100644
index 0000000..bf49b23
--- /dev/null
+++ b/rosidl_adapter_proto/bin/rosidl_adapter_proto
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+import argparse
+import sys
+import pathlib
+import os
+
+from rosidl_cmake import read_generator_arguments
+from rosidl_adapter_proto import generate_proto
+from rosidl_adapter_proto import compile_proto
+
+def main(argv=sys.argv[1:]):
+ parser = argparse.ArgumentParser(
+ description='Generate the Protobuf interfaces for Protobuf type support.',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument(
+ '--generator-arguments-file',
+ required=True,
+ help='The location of the file containing the generator arguments')
+ parser.add_argument(
+ '--protoc-path',
+ required=True,
+ help='Path to the protoc executable')
+
+ args = parser.parse_args(argv)
+
+ generator_args = read_generator_arguments(args.generator_arguments_file)
+
+ # Generate .proto files
+ rc = generate_proto(args.generator_arguments_file)
+ if rc:
+ return rc
+
+ # Compile .proto files using protoc
+ cpp_out_dir = str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())
+ proto_path_list = [str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())]
+ proto_files = []
+ package_name = generator_args["package_name"]
+
+ if "additional_files" in generator_args:
+ proto_path_list += generator_args["additional_files"]
+
+ pathlib.Path(cpp_out_dir).mkdir(parents=True, exist_ok=True)
+
+ for idl_tuple in generator_args.get('idl_tuples', []):
+ idl_parts = idl_tuple.rsplit(':', 1)
+ assert len(idl_parts) == 2
+ idl_rel_path = pathlib.Path(idl_parts[1])
+ idl_stem = idl_rel_path.stem
+ generated_file = os.path.join(
+ generator_args['output_dir'],
+ str(idl_rel_path.parent),
+ idl_stem + ".proto"
+ )
+ proto_files.append(str(pathlib.Path(generated_file).resolve()))
+
+ # compile proto files with protoc
+ rc = compile_proto(protoc_path = args.protoc_path,
+ proto_path_list = proto_path_list,
+ cpp_out_dir = cpp_out_dir,
+ proto_files = proto_files,
+ package_name = package_name
+ )
+
+ return rc
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/rosidl_adapter_proto/cmake/rosidl_adapt_proto_interfaces.cmake b/rosidl_adapter_proto/cmake/rosidl_adapt_proto_interfaces.cmake
new file mode 100644
index 0000000..230e933
--- /dev/null
+++ b/rosidl_adapter_proto/cmake/rosidl_adapt_proto_interfaces.cmake
@@ -0,0 +1,96 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+find_package(PythonInterp REQUIRED)
+if(NOT PYTHON_EXECUTABLE)
+ message(FATAL_ERROR "Variable 'PYTHON_EXECUTABLE' must not be empty")
+endif()
+
+set(rosidl_adapter_proto_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/rosidl_adapter_proto/${PROJECT_NAME}")
+
+# Create a list of proto directories
+set(_proto_include_dirs "")
+foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
+ set(_proto_dir "${${_pkg_name}_DIR}/../../../share/")
+ normalize_path(_proto_dir "${_proto_dir}")
+ list(APPEND _proto_include_dirs "${_proto_dir}")
+endforeach()
+
+set(_target_dependencies
+ "${rosidl_adapter_proto_BIN}"
+ ${rosidl_adapter_proto_GENERATOR_FILES}
+ ${rosidl_generate_interfaces_ABS_IDL_FILES}
+ ${_proto_include_dirs})
+foreach(dep ${_target_dependencies})
+ if(NOT EXISTS "${dep}")
+ message(FATAL_ERROR "Target dependency '${dep}' does not exist")
+ endif()
+endforeach()
+
+# Write all this to a file to work around command line length limitations on some platforms
+set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_adapter_proto__arguments.json")
+rosidl_write_generator_arguments(
+ "${generator_arguments_file}"
+ PACKAGE_NAME "${PROJECT_NAME}"
+ IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}"
+ OUTPUT_DIR "${rosidl_adapter_proto_OUTPUT_DIR}"
+ TEMPLATE_DIR "${rosidl_adapter_proto_TEMPLATE_DIR}"
+ TARGET_DEPENDENCIES ${_target_dependencies}
+ ADDITIONAL_FILES "${_proto_include_dirs}")
+
+execute_process(
+ COMMAND "${PYTHON_EXECUTABLE}" "${rosidl_adapter_proto_BIN}"
+ --generator-arguments-file "${generator_arguments_file}"
+ --protoc-path "${Protobuf_PROTOC_EXECUTABLE}"
+ ERROR_VARIABLE error
+ RESULT_VARIABLE result
+)
+
+if(NOT result EQUAL 0)
+ message(FATAL_ERROR "Proto file generation failed, error code: ${error}")
+endif()
+
+set(rosidl_adapter_proto_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/rosidl_adapter_proto")
+foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES})
+ get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY)
+ get_filename_component(_parent_folder "${_parent_folder}" NAME)
+ get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE)
+ list(APPEND rosidl_adapter_proto_GENERATED_CPP "${rosidl_adapter_proto_OUTPUT_DIR}/${_parent_folder}/${_idl_name}.pb.cc")
+endforeach()
+
+# generate header to switch between export and import for a specific package
+set(rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER
+"${rosidl_adapter_proto_OUTPUT_DIR}/rosidl_adapter_proto__visibility_control.h")
+string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER)
+configure_file(
+ "${rosidl_adapter_proto_TEMPLATE_DIR}/rosidl_adapter_proto__visibility_control.h.in"
+ "${rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER}"
+ @ONLY
+)
+
+install(
+ DIRECTORY ${rosidl_adapter_proto_OUTPUT_DIR}
+ DESTINATION "include/"
+ PATTERN "*.h"
+)
+
+install(
+ DIRECTORY ${rosidl_adapter_proto_OUTPUT_DIR}
+ DESTINATION "share/"
+ PATTERN "*.proto"
+)
\ No newline at end of file
diff --git a/rosidl_adapter_proto/cmake/rosidl_adapter_proto-extras.cmake.in b/rosidl_adapter_proto/cmake/rosidl_adapter_proto-extras.cmake.in
new file mode 100644
index 0000000..24acbaa
--- /dev/null
+++ b/rosidl_adapter_proto/cmake/rosidl_adapter_proto-extras.cmake.in
@@ -0,0 +1,52 @@
+# generated from
+# rosidl_adapter_proto/
+# rosidl_adapter_proto-extras.cmake.in
+
+find_package(Protobuf REQUIRED)
+
+if(NOT Protobuf_FOUND)
+ message(STATUS "Could not find Protobuf - skip rosidl_adapter_proto")
+else()
+ find_package(ament_cmake_core QUIET REQUIRED)
+ ament_register_extension(
+ "rosidl_generate_idl_interfaces"
+ "rosidl_adapter_proto"
+ "${rosidl_adapter_proto_DIR}/rosidl_adapt_proto_interfaces.cmake")
+
+ set(rosidl_adapter_proto_BIN
+ "${rosidl_adapter_proto_DIR}/../../../lib/rosidl_adapter_proto/rosidl_adapter_proto")
+ normalize_path(rosidl_adapter_proto_BIN
+ "${rosidl_adapter_proto_BIN}")
+
+ set(rosidl_adapter_proto_GENERATOR_FILES
+ "${rosidl_adapter_proto_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_adapter_proto/__init__.py")
+ normalize_path(rosidl_adapter_proto_GENERATOR_FILES
+ "${rosidl_adapter_proto_GENERATOR_FILES}")
+
+ set(rosidl_adapter_proto_TEMPLATE_DIR
+ "${rosidl_adapter_proto_DIR}/../resource")
+ normalize_path(rosidl_adapter_proto_TEMPLATE_DIR
+ "${rosidl_adapter_proto_TEMPLATE_DIR}")
+
+ include("${rosidl_adapter_proto_DIR}/rosidl_adapt_proto_interfaces.cmake")
+
+ add_compile_definitions("ROSIDL_ADAPTER_PROTO_BUILDING_DLL__${PROJECT_NAME}")
+
+ # There is no clean way to include additional files into protobuf headers
+ if(NOT WIN32)
+ add_compile_options("-include${rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER}")
+ else()
+ add_compile_options( "/FI\"${rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER}\"")
+ endif()
+
+ foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
+ set(_proto_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/rosidl_adapter_proto__visibility_control.h")
+ normalize_path(_proto_dir "${_proto_dir}")
+ if(NOT WIN32)
+ add_compile_options("-include${_proto_dir}")
+ else()
+ add_compile_options( "/FI\"${_proto_dir}\"")
+ endif()
+ endforeach()
+
+endif()
\ No newline at end of file
diff --git a/rosidl_adapter_proto/package.xml b/rosidl_adapter_proto/package.xml
new file mode 100644
index 0000000..7b0a027
--- /dev/null
+++ b/rosidl_adapter_proto/package.xml
@@ -0,0 +1,23 @@
+
+
+
+ rosidl_adapter_proto
+ 0.0.1
+ Generate the Protobuf interfaces for Protobuf serialization.
+ Aleksandar Brakmić
+ Apache License 2.0
+
+ ament_cmake
+
+ python3-empy
+ rosidl_cli
+ rosidl_parser
+
+ rosidl_interface_packages
+
+
+
+ ament_cmake
+ proto
+
+
\ No newline at end of file
diff --git a/rosidl_adapter_proto/resource/action.proto.em b/rosidl_adapter_proto/resource/action.proto.em
new file mode 100644
index 0000000..5cd66b6
--- /dev/null
+++ b/rosidl_adapter_proto/resource/action.proto.em
@@ -0,0 +1,63 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+import rosidl_parser.definition as rosidl
+
+from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX
+from rosidl_adapter_proto import MSG_TYPE_TO_PROTO
+from rosidl_adapter_proto import PROTO_ACTION_SEND_GOAL_CALL_NAME
+from rosidl_adapter_proto import PROTO_ACTION_GET_RESULT_CALL_NAME
+
+}@
+option cc_generic_services = true;
+
+@#
+@# ================ Message definitions ================
+@#
+@[for message in [action.goal,
+ action.send_goal_service.request_message,
+ action.send_goal_service.response_message,
+ action.result,
+ action.get_result_service.request_message,
+ action.get_result_service.response_message,
+ action.feedback,
+ action.feedback_message,
+ ]
+]@
+@{
+TEMPLATE(
+ 'msg.proto.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=message,
+)
+}@
+
+
+@[end for]@
+@#
+@# ================ Service definitions ================
+@#
+service @(action.namespaced_type.name)
+{
+ rpc @(PROTO_ACTION_SEND_GOAL_CALL_NAME) (@(action.send_goal_service.request_message.structure.namespaced_type.name)) returns (@(action.send_goal_service.response_message.structure.namespaced_type.name));
+ rpc @(PROTO_ACTION_GET_RESULT_CALL_NAME) (@(action.get_result_service.request_message.structure.namespaced_type.name)) returns (@(action.get_result_service.response_message.structure.namespaced_type.name));
+}
\ No newline at end of file
diff --git a/rosidl_adapter_proto/resource/idl.proto.em b/rosidl_adapter_proto/resource/idl.proto.em
new file mode 100644
index 0000000..56f8c18
--- /dev/null
+++ b/rosidl_adapter_proto/resource/idl.proto.em
@@ -0,0 +1,127 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX
+}@
+// generated from rosidl_adapter_proto/resource/idl.proto.em
+// with input from @(package_name):@(interface_path)
+// generated code does not contain a copyright notice
+
+syntax = "proto3";
+
+package @('.'.join([package_name] + list(interface_path.parts)[:-1] + [PROTO_PACKAGE_POSTFIX]));
+
+@{
+#######################################################################
+# Protobuf imports
+#######################################################################
+from rosidl_adapter_proto import collect_proto_imports
+from rosidl_adapter_proto import to_proto_import
+import rosidl_parser.definition as rosidl
+
+proto_import_set = set()
+already_imported = set()
+
+# Collect imports from plain messages
+for message in content.get_elements_of_type(rosidl.Message):
+ proto_import_set |= collect_proto_imports(message)
+
+ already_imported.add(to_proto_import(message.structure.namespaced_type))
+
+# Collect imports from services
+for service in content.get_elements_of_type(rosidl.Service):
+ proto_import_set |= collect_proto_imports(service.request_message)
+ proto_import_set |= collect_proto_imports(service.response_message)
+
+ already_imported.add(to_proto_import(service.namespaced_type))
+ already_imported.add(to_proto_import(service.request_message.structure.namespaced_type))
+ already_imported.add(to_proto_import(service.response_message.structure.namespaced_type))
+
+# Collect imports from actions
+for action in content.get_elements_of_type(rosidl.Action):
+ proto_import_set |= collect_proto_imports(action.goal)
+ proto_import_set |= collect_proto_imports(action.send_goal_service.request_message)
+ proto_import_set |= collect_proto_imports(action.send_goal_service.response_message)
+ proto_import_set |= collect_proto_imports(action.result)
+ proto_import_set |= collect_proto_imports(action.get_result_service.request_message)
+ proto_import_set |= collect_proto_imports(action.get_result_service.response_message)
+ proto_import_set |= collect_proto_imports(action.feedback)
+ proto_import_set |= collect_proto_imports(action.feedback_message)
+
+ already_imported.add(to_proto_import(action.namespaced_type))
+ already_imported.add(to_proto_import(action.goal.structure.namespaced_type))
+ already_imported.add(to_proto_import(action.send_goal_service.request_message.structure.namespaced_type))
+ already_imported.add(to_proto_import(action.send_goal_service.response_message.structure.namespaced_type))
+ already_imported.add(to_proto_import(action.result.structure.namespaced_type))
+ already_imported.add(to_proto_import(action.get_result_service.request_message.structure.namespaced_type))
+ already_imported.add(to_proto_import(action.get_result_service.response_message.structure.namespaced_type))
+ already_imported.add(to_proto_import(action.feedback.structure.namespaced_type))
+ already_imported.add(to_proto_import(action.feedback_message.structure.namespaced_type))
+
+for already_imported_proto_file in already_imported:
+ if already_imported_proto_file in proto_import_set:
+ proto_import_set.remove(already_imported_proto_file)
+}@
+@[for import_proto_file_path in proto_import_set]@
+import "@(import_proto_file_path)";
+@[end for]@
+@#
+@# Newline after import statements
+@#
+@[if len(proto_import_set) != 0]@
+
+@[end if]@
+@{
+#######################################################################
+# Handle message
+#######################################################################
+from rosidl_parser.definition import Message
+for message in content.get_elements_of_type(Message):
+ TEMPLATE(
+ 'msg.proto.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=message,
+ )
+
+########################################################################
+## Handle service
+########################################################################
+from rosidl_parser.definition import Service
+for service in content.get_elements_of_type(Service):
+ TEMPLATE(
+ 'srv.proto.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ service=service,
+ )
+
+########################################################################
+## Handle action
+########################################################################
+from rosidl_parser.definition import Action
+for action in content.get_elements_of_type(Action):
+ TEMPLATE(
+ 'action.proto.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ action=action,
+ )
+}@
\ No newline at end of file
diff --git a/rosidl_adapter_proto/resource/msg.proto.em b/rosidl_adapter_proto/resource/msg.proto.em
new file mode 100644
index 0000000..c120a5a
--- /dev/null
+++ b/rosidl_adapter_proto/resource/msg.proto.em
@@ -0,0 +1,143 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+import rosidl_parser.definition as rosidl
+
+from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX
+from rosidl_adapter_proto import MSG_TYPE_TO_PROTO
+from rosidl_adapter_proto import compute_proto_field_number
+
+import sys
+import re
+
+}@
+@#
+@# ================ Message definition ================
+@#
+@{
+comment = ""
+for annotation in message.structure.annotations:
+ if (annotation.name == "verbatim") \
+ and ("language" in annotation.value) \
+ and (annotation.value["language"] == "comment") \
+ and ("text" in annotation.value):
+ comment = "//" + re.sub(r"\\n", "\n//", annotation.value["text"])
+ break
+}@
+@[if comment != ""]@
+@(comment)
+@[end if]@
+message @(message.structure.namespaced_type.name)
+{
+
+@# Message fields
+@{
+used_field_numbers = set()
+proto_member_list = []
+
+str_max_len_type = 0
+str_max_len_name = 0
+str_max_len_field_number = 0
+
+for member in message.structure.members:
+
+ idl_type = member.type
+
+ is_repeated = False
+ is_byte_type = False
+ is_char_type = False
+
+ # Check if datatype is repeated
+ if isinstance(idl_type, rosidl.AbstractNestedType):
+ is_repeated = True
+ idl_type = idl_type.value_type
+
+ # Check for actual datatype
+ if isinstance(idl_type, rosidl.BasicType):
+ proto_type = MSG_TYPE_TO_PROTO[idl_type.typename]
+ if idl_type.typename in [rosidl.OCTET_TYPE, 'uint8', 'int8']:
+ is_byte_type = True
+ elif idl_type.typename in rosidl.CHARACTER_TYPES:
+ is_char_type = True
+ elif isinstance(idl_type, rosidl.AbstractString):
+ proto_type = "string"
+ elif isinstance(idl_type, rosidl.AbstractWString):
+ proto_type = "bytes"
+ elif isinstance(idl_type, rosidl.NamespacedType):
+ proto_type = ".".join(idl_type.namespaces + [PROTO_PACKAGE_POSTFIX] + [idl_type.name])
+ elif isinstance(idl_type, rosidl.NamedType):
+ proto_type = idl_type.name
+
+ # Check if we can improve the repeated field with a scalar type
+ if is_repeated:
+ if is_byte_type:
+ proto_type = "bytes"
+ elif is_char_type:
+ proto_type = "string"
+ else:
+ proto_type = "repeated " + proto_type
+
+ # Compute a field number of the actual variable name. This will almost always be unique.
+ member_name_for_field_number = member.name
+ additional_counter = 0
+
+ field_number = compute_proto_field_number(member_name_for_field_number)
+
+ while field_number in used_field_numbers:
+ sys.stderr.write("WARNING: Field " + member.name + " maps to a protobuf field number that is already in use. This will hurt the downward compatibility of this message..\n")
+ member_name_for_field_number = member.name + str(additional_counter)
+ field_number = compute_proto_field_number(member_name_for_field_number)
+ additional_counter += 1
+
+ used_field_numbers.add(field_number)
+
+ member_dict = {
+ "type": proto_type,
+ "name": member.name,
+ "field_number": field_number,
+ }
+
+ for annotation in member.annotations:
+ if (annotation.name == "verbatim") \
+ and ("language" in annotation.value) \
+ and (annotation.value["language"] == "comment") \
+ and ("text" in annotation.value):
+ member_dict["comment"] = " //" + re.sub(r"\\n", "\n //", annotation.value["text"])
+ if (annotation.name == "unit") and ("value" in annotation.value):
+ member_dict["unit"] = annotation.value["value"]
+
+
+ proto_member_list.append(member_dict)
+
+ str_max_len_type = max(str_max_len_type, len(proto_type))
+ str_max_len_name = max(str_max_len_name, len(member.name))
+ str_max_len_field_number = max(str_max_len_field_number, len(str(field_number)))
+}@
+@[for proto_member in proto_member_list]@
+@[ if "comment" in proto_member]@
+
+@(proto_member["comment"])
+@[ end if]@
+ @(str.ljust(proto_member["type"], str_max_len_type)) @(str.ljust(proto_member["name"], str_max_len_name)) = @(str.rjust(str(proto_member["field_number"]), str_max_len_field_number));@
+@[ if "unit" in proto_member]@
+ // [@(proto_member["unit"])@]@
+@[ end if]
+@[end for]@
+}
\ No newline at end of file
diff --git a/rosidl_adapter_proto/resource/rosidl_adapter_proto__visibility_control.h.in b/rosidl_adapter_proto/resource/rosidl_adapter_proto__visibility_control.h.in
new file mode 100644
index 0000000..b88fe70
--- /dev/null
+++ b/rosidl_adapter_proto/resource/rosidl_adapter_proto__visibility_control.h.in
@@ -0,0 +1,42 @@
+// generated from
+// rosidl_typesupport_protobuf/rosidl_adapter_proto/resource/rosidl_adapter_proto__visibility_control.h.in
+// generated code does not contain a copyright notice
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// This logic was borrowed (then namespaced) from the examples on the gcc wiki:
+// https://gcc.gnu.org/wiki/Visibility
+
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef __GNUC__
+ #define ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@ __attribute__ ((dllexport))
+ #define ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@ __attribute__ ((dllimport))
+ #else
+ #define ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@ __declspec(dllexport)
+ #define ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@ __declspec(dllimport)
+ #endif
+ #ifdef ROSIDL_ADAPTER_PROTO_BUILDING_DLL__@PROJECT_NAME@
+ #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@ ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@
+ #else
+ #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@ ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@
+ #endif
+ #define ROSIDL_ADAPTER_PROTO_LOCAL__@PROJECT_NAME@
+#else
+ #define ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@ __attribute__ ((visibility("default")))
+ #define ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@
+ #if __GNUC__ >= 4
+ #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@ __attribute__ ((visibility("default")))
+ #define ROSIDL_ADAPTER_PROTO_LOCAL__@PROJECT_NAME@ __attribute__ ((visibility("hidden")))
+ #else
+ #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@
+ #define ROSIDL_ADAPTER_PROTO_LOCAL__@PROJECT_NAME@
+ #endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/rosidl_adapter_proto/resource/srv.proto.em b/rosidl_adapter_proto/resource/srv.proto.em
new file mode 100644
index 0000000..e25b279
--- /dev/null
+++ b/rosidl_adapter_proto/resource/srv.proto.em
@@ -0,0 +1,60 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+import rosidl_parser.definition as rosidl
+
+from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX
+from rosidl_adapter_proto import MSG_TYPE_TO_PROTO
+from rosidl_adapter_proto import PROTO_SERVICE_CALL_NAME
+
+}@
+option cc_generic_services = true;
+
+@#
+@# ================ Message definitions ================
+@#
+@{
+TEMPLATE(
+ 'msg.proto.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.request_message,
+)
+}@
+
+
+@{
+TEMPLATE(
+ 'msg.proto.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.response_message,
+)
+}@
+
+
+@#
+@# ================ Service definitions ================
+@#
+service @(service.namespaced_type.name)
+{
+ rpc @(PROTO_SERVICE_CALL_NAME) (@(service.request_message.structure.namespaced_type.name)) returns (@(service.response_message.structure.namespaced_type.name));
+}
\ No newline at end of file
diff --git a/rosidl_adapter_proto/rosidl_adapter_proto/__init__.py b/rosidl_adapter_proto/rosidl_adapter_proto/__init__.py
new file mode 100644
index 0000000..5abe056
--- /dev/null
+++ b/rosidl_adapter_proto/rosidl_adapter_proto/__init__.py
@@ -0,0 +1,114 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+from rosidl_cmake import generate_files
+
+import rosidl_parser.definition as rosidl
+
+import subprocess
+import zlib
+
+# A postfix for the protobuf package name / the c++ namespace
+PROTO_PACKAGE_POSTFIX = "pb"
+
+# The rpc-function name for service calls. As ros services can only offer a
+# single function, this function gets a static name in the protobuf service
+PROTO_SERVICE_CALL_NAME = "Call"
+
+# The rpc function name for sending an action goal
+PROTO_ACTION_SEND_GOAL_CALL_NAME = "SendGoal"
+
+# The rpc function name for retrieving the action result
+PROTO_ACTION_GET_RESULT_CALL_NAME = "GetResult"
+
+# A Mapping from IDL -> Protobuf type
+MSG_TYPE_TO_PROTO = {
+ 'boolean': 'bool',
+ 'octet': 'uint32',
+ 'char': 'uint32',
+ 'wchar': 'uint32',
+ 'float': 'float',
+ 'double': 'double',
+ 'long double': 'double',
+ 'uint8': 'uint32',
+ 'int8': 'int32',
+ 'uint16': 'uint32',
+ 'int16': 'int32',
+ 'uint32': 'fixed32',
+ 'int32': 'sfixed32',
+ 'uint64': 'fixed64',
+ 'int64': 'sfixed64',
+ 'string': 'string',
+ 'wstring': 'bytes',
+}
+
+field_val = 0
+
+def compute_proto_field_number(variable_name):
+ # Field number rules (https://developers.google.com/protocol-buffers/docs/proto#assigning_field_numbers)
+ #
+ # Smallest: 1
+ # Largest: 536870911 (= 2^29 - 1)
+ #
+ # Reserved Range: 19000 to 19999 (=> 1000 values)
+
+ field_number = zlib.crc32(bytearray(variable_name, 'utf8')) # Create a 32 bit hash from the variable name
+ field_number = (field_number % (536870911 - 1000)) # Reduce to the correct amount of values
+ field_number += 1 # Account for the fact that we must not use 0
+ if field_number >= 19000:
+ field_number += 1000 # Account for the fact that we must not use 19000 to 19999
+
+ return field_number
+
+def to_proto_import(namespaced_type):
+ assert isinstance(namespaced_type, rosidl.NamespacedType)
+ return "/".join(namespaced_type.namespaces + [namespaced_type.name]) + ".proto"
+
+def collect_proto_imports(rosidl_message):
+ assert isinstance(rosidl_message, rosidl.Message)
+ import_set = set()
+
+ for member in rosidl_message.structure.members:
+ if isinstance(member.type, rosidl.NamespacedType):
+ namespaced_type = member.type
+ elif isinstance(member.type, rosidl.AbstractNestedType) \
+ and isinstance(member.type.value_type, rosidl.NamespacedType):
+ namespaced_type = member.type.value_type
+ else:
+ continue
+
+ import_set.add(to_proto_import(namespaced_type))
+
+ return import_set
+
+def generate_proto(generator_arguments_file):
+ mapping = {
+ 'idl.proto.em': '%s.proto',
+ }
+ generate_files(generator_arguments_file, mapping, keep_case=True)
+ return 0
+
+def compile_proto(protoc_path, proto_path_list, cpp_out_dir, proto_files, package_name):
+ protoc_cmd = [protoc_path]
+
+ for path in proto_path_list:
+ protoc_cmd.append("--proto_path=" + path)
+
+ protoc_cmd.append(f"--cpp_out=dllexport_decl=ROSIDL_ADAPTER_PROTO_PUBLIC__{package_name}:{cpp_out_dir}")
+ protoc_cmd = protoc_cmd + proto_files
+
+ subprocess.check_call(protoc_cmd)
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/CHANGELOG.rst b/rosidl_typesupport_protobuf/CHANGELOG.rst
new file mode 100644
index 0000000..6694d49
--- /dev/null
+++ b/rosidl_typesupport_protobuf/CHANGELOG.rst
@@ -0,0 +1,3 @@
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Changelog for package rosidl_typesupport_protobuf_cpp
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/CMakeLists.txt b/rosidl_typesupport_protobuf/CMakeLists.txt
new file mode 100644
index 0000000..f881b69
--- /dev/null
+++ b/rosidl_typesupport_protobuf/CMakeLists.txt
@@ -0,0 +1,36 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+cmake_minimum_required(VERSION 3.5)
+
+project(rosidl_typesupport_protobuf)
+
+find_package(ament_cmake REQUIRED)
+find_package(ament_cmake_python REQUIRED)
+find_package(rosidl_generator_c REQUIRED)
+
+ament_export_include_directories(include)
+
+ament_python_install_package(${PROJECT_NAME})
+
+install(
+ DIRECTORY include/
+ DESTINATION include
+)
+
+ament_package(CONFIG_EXTRAS "cmake/discover-ros-distro-extras.cmake")
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/cmake/discover-ros-distro-extras.cmake b/rosidl_typesupport_protobuf/cmake/discover-ros-distro-extras.cmake
new file mode 100644
index 0000000..47d6000
--- /dev/null
+++ b/rosidl_typesupport_protobuf/cmake/discover-ros-distro-extras.cmake
@@ -0,0 +1,46 @@
+# ========================= RMW eCAL LICENSE =================================
+#
+# Copyright (C) 2019 - 2020 Continental Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ========================= RMW eCAL LICENSE =================================
+
+set(supported_distros
+ dashing
+ eloquent
+ foxy
+ rolling
+)
+
+list(FIND supported_distros $ENV{ROS_DISTRO} index)
+if(index EQUAL -1)
+ message(FATAL_ERROR "'$ENV{ROS_DISTRO}' is an unsupported ros2 distro.")
+endif()
+
+list(FIND supported_distros foxy foxy_index)
+
+if(${index} GREATER_EQUAL ${foxy_index})
+ set(is_foxy_or_greater true)
+else()
+ set(is_foxy_or_greater false)
+endif()
+
+
+set(distro_index 0)
+foreach(distro ${supported_distros})
+ add_compile_definitions("$=${distro_index}")
+ MATH(EXPR distro_index "${distro_index}+1")
+endforeach()
+
+add_compile_definitions("ROS_DISTRO=$")
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support.hpp b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support.hpp
new file mode 100644
index 0000000..33ef29b
--- /dev/null
+++ b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support.hpp
@@ -0,0 +1,39 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+namespace rosidl_typesupport_protobuf
+{
+
+typedef struct message_type_support_t
+{
+ const char * message_namespace;
+ const char * message_name;
+
+ bool (* serialize)(const void * ros_message, std::string& serialized_message);
+ bool (* deserialize)(void * ros_message, const void *serialized_data, size_t size);
+ std::string (*get_descriptor)();
+
+} message_type_support_t;
+
+}
+
diff --git a/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support_decl.hpp b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support_decl.hpp
new file mode 100644
index 0000000..93d3179
--- /dev/null
+++ b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support_decl.hpp
@@ -0,0 +1,35 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+//rosidl_message_type_support_t
+#include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp"
+
+namespace rosidl_typesupport_protobuf
+{
+
+// This is implemented in the shared library provided by this package.
+template
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+const rosidl_message_type_support_t * get_message_type_support_handle();
+
+} // namespace rosidl_typesupport_protobuf_cpp
diff --git a/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/proto_descriptor_helper.hpp b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/proto_descriptor_helper.hpp
new file mode 100644
index 0000000..0d71133
--- /dev/null
+++ b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/proto_descriptor_helper.hpp
@@ -0,0 +1,101 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+// protobuf includes
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4100 4127 4146 4800) // disable proto warnings
+#endif
+#include
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+
+inline bool HasFile(const google::protobuf::FileDescriptorSet& fset_, const std::string& fname_)
+{
+ for (auto findex = 0; findex < fset_.file_size(); ++findex)
+ {
+ if (fset_.file(findex).name() == fname_)
+ {
+ return(true);
+ }
+ }
+ return(false);
+}
+
+inline bool GetFileDescriptor(const google::protobuf::Descriptor* desc_, google::protobuf::FileDescriptorSet& fset_)
+{
+
+ if (desc_ == nullptr) return(false);
+ const google::protobuf::FileDescriptor* fdesc = desc_->file();
+
+ for (auto dep = 0; dep < fdesc->dependency_count(); ++dep)
+ {
+ // iterate containing messages
+ const google::protobuf::FileDescriptor* sfdesc = fdesc->dependency(dep);
+
+ for (auto mtype = 0; mtype < sfdesc->message_type_count(); ++mtype)
+ {
+ const google::protobuf::Descriptor* desc = sfdesc->message_type(mtype);
+ GetFileDescriptor(desc, fset_);
+ }
+
+ // containing enums ?
+ if (sfdesc->enum_type_count() > 0)
+ {
+ const google::protobuf::EnumDescriptor* edesc = sfdesc->enum_type(0);
+ const google::protobuf::FileDescriptor* efdesc = edesc->file();
+
+ if (!HasFile(fset_, efdesc->name()))
+ {
+ google::protobuf::FileDescriptorProto* epdesc = fset_.add_file();
+ efdesc->CopyTo(epdesc);
+ }
+ }
+
+
+ // containing services ?
+ if (sfdesc->service_count() > 0)
+ {
+ const google::protobuf::ServiceDescriptor* svdesc = sfdesc->service(0);
+ const google::protobuf::FileDescriptor* svfdesc = svdesc->file();
+
+ if (!HasFile(fset_, svfdesc->name()))
+ {
+ google::protobuf::FileDescriptorProto* svpdesc = fset_.add_file();
+ svfdesc->CopyTo(svpdesc);
+ }
+ }
+ }
+
+ if (HasFile(fset_, fdesc->name())) return(true);
+
+ google::protobuf::FileDescriptorProto* pdesc = fset_.add_file();
+ fdesc->CopyTo(pdesc);
+ for (auto field = 0; field < desc_->field_count(); ++field)
+ {
+ const google::protobuf::FieldDescriptor* fddesc = desc_->field(field);
+ const google::protobuf::Descriptor* desc = fddesc->message_type();
+ GetFileDescriptor(desc, fset_);
+ }
+
+ return(true);
+}
+
+template
+inline std::string GetProtoMessageDescription()
+{
+ const google::protobuf::Descriptor* desc = T::descriptor();
+ google::protobuf::FileDescriptorSet pset;
+ if (GetFileDescriptor(desc, pset))
+ {
+ std::string desc_s = pset.SerializeAsString();
+ return(desc_s);
+ }
+ return("");
+}
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp
new file mode 100644
index 0000000..6fcf54c
--- /dev/null
+++ b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp
@@ -0,0 +1,153 @@
+/* ========================= RMW eCAL LICENSE =================================
+*
+* Copyright (C) 2019 - 2020 Continental Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* ========================= RMW eCAL LICENSE =================================
+*/
+
+//From Foxy distro rosidl_generator_c has been renamed to rosidl_generator_c,
+//purpose of this header file is to alias old C type names to new ones, that way the
+//rest of the code doesn't have to care about old package name regardless of distro.
+//any rosidl_generator_c to rosidl_runtime_c adaptions should be added here
+
+#pragma once
+
+#if ROS_DISTRO >= FOXY
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#else
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(STRUCT_NAME) \
+ using rosidl_runtime_c__##STRUCT_NAME##__Sequence = rosidl_generator_c__##STRUCT_NAME##__Sequence;
+
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(float)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(double)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(long_double)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(char)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(wchar)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(boolean)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(octet)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(uint8)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(int8)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(uint16)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(int16)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(uint32)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(int32)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(uint64)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(int64)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(String)
+ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE(U16String)
+
+#undef ADAPT_PRIMITIVE_SEQUENCE_NAMESPACE
+
+using rosidl_runtime_c__String = rosidl_generator_c__String;
+using rosidl_runtime_c__U16String = rosidl_generator_c__U16String;
+
+#define rosidl_runtime_c__float__Sequence__fini(sequence) rosidl_generator_c__float__Sequence__fini(sequence)
+#define rosidl_runtime_c__float__Sequence__init(sequence, size) rosidl_generator_c__float__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__double__Sequence__fini(sequence) rosidl_generator_c__double__Sequence__fini(sequence)
+#define rosidl_runtime_c__double__Sequence__init(sequence, size) rosidl_generator_c__double__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__long_double__Sequence__fini(sequence) rosidl_generator_c__long_double__Sequence__fini(sequence)
+#define rosidl_runtime_c__long_double__Sequence__init(sequence, size) rosidl_generator_c__long_double__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__char__Sequence__fini(sequence) rosidl_generator_c__char__Sequence__fini(sequence)
+#define rosidl_runtime_c__char__Sequence__init(sequence, size) rosidl_generator_c__char__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__wchar__Sequence__fini(sequence) rosidl_generator_c__wchar__Sequence__fini(sequence)
+#define rosidl_runtime_c__wchar__Sequence__init(sequence, size) rosidl_generator_c__wchar__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__boolean__Sequence__fini(sequence) rosidl_generator_c__boolean__Sequence__fini(sequence)
+#define rosidl_runtime_c__boolean__Sequence__init(sequence, size) rosidl_generator_c__boolean__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__octet__Sequence__fini(sequence) rosidl_generator_c__octet__Sequence__fini(sequence)
+#define rosidl_runtime_c__octet__Sequence__init(sequence, size) rosidl_generator_c__octet__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__uint8__Sequence__fini(sequence) rosidl_generator_c__uint8__Sequence__fini(sequence)
+#define rosidl_runtime_c__uint8__Sequence__init(sequence, size) rosidl_generator_c__uint8__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__int8__Sequence__fini(sequence) rosidl_generator_c__int8__Sequence__fini(sequence)
+#define rosidl_runtime_c__int8__Sequence__init(sequence, size) rosidl_generator_c__int8__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__uint16__Sequence__fini(sequence) rosidl_generator_c__uint16__Sequence__fini(sequence)
+#define rosidl_runtime_c__uint16__Sequence__init(sequence, size) rosidl_generator_c__uint16__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__int16__Sequence__fini(sequence) rosidl_generator_c__int16__Sequence__fini(sequence)
+#define rosidl_runtime_c__int16__Sequence__init(sequence, size) rosidl_generator_c__int16__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__uint32__Sequence__fini(sequence) rosidl_generator_c__uint32__Sequence__fini(sequence)
+#define rosidl_runtime_c__uint32__Sequence__init(sequence, size) rosidl_generator_c__uint32__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__int32__Sequence__fini(sequence) rosidl_generator_c__int32__Sequence__fini(sequence)
+#define rosidl_runtime_c__int32__Sequence__init(sequence, size) rosidl_generator_c__int32__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__uint64__Sequence__fini(sequence) rosidl_generator_c__uint64__Sequence__fini(sequence)
+#define rosidl_runtime_c__uint64__Sequence__init(sequence, size) rosidl_generator_c__uint64__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__int64__Sequence__fini(sequence) rosidl_generator_c__int64__Sequence__fini(sequence)
+#define rosidl_runtime_c__int64__Sequence__init(sequence, size) rosidl_generator_c__int64__Sequence__init(sequence, size)
+
+#define rosidl_runtime_c__bool__Sequence__init(sequence, size) rosidl_generator_c__bool__Sequence__init(sequence, size)
+#define rosidl_runtime_c__bool__Sequence__fini(sequence) rosidl_generator_c__bool__Sequence__init(sequence)
+
+#define rosidl_runtime_c__byte__Sequence__init(sequence, size) rosidl_generator_c__byte__Sequence__init(sequence, size)
+#define rosidl_runtime_c__byte__Sequence__fini(sequence) rosidl_generator_c__byte__Sequence__fini(sequence)
+
+#define rosidl_runtime_c__float32__Sequence__init(sequence, size) rosidl_generator_c__float32__Sequence__init(sequence, size)
+#define rosidl_runtime_c__float32__Sequence__fini(sequence) rosidl_generator_c__float32__Sequence__fini(sequence)
+
+#define rosidl_runtime_c__float64__Sequence__init(sequence, size) rosidl_generator_c__float64__Sequence__init(sequence, size)
+#define rosidl_runtime_c__float64__Sequence__fini(sequence) rosidl_generator_c__float64__Sequence__fini(sequence)
+
+#define rosidl_runtime_c__String__init(str) rosidl_generator_c__String__init(str)
+#define rosidl_runtime_c__String__fini(str) rosidl_generator_c__String__fini(str)
+#define rosidl_runtime_c__String__assignn(str, value, n) rosidl_generator_c__String__assignn(str, value, n)
+#define rosidl_runtime_c__String__assign(str, value) rosidl_generator_c__String__assign(str, value)
+#define rosidl_runtime_c__String__Sequence__init(sequence, size) rosidl_generator_c__String__Sequence__init(sequence, size)
+#define rosidl_runtime_c__String__Sequence__fini(sequence) rosidl_generator_c__String__Sequence__fini(sequence)
+#define rosidl_runtime_c__String__Sequence__create(size) rosidl_generator_c__String__Sequence__create(size)
+#define rosidl_runtime_c__String__Sequence__destroy(sequence) rosidl_generator_c__String__Sequence__destroy(sequence)
+
+#define rosidl_runtime_c__U16String__init(str) rosidl_generator_c__U16String__init(str)
+#define rosidl_runtime_c__U16String__fini(str) rosidl_generator_c__U16String__fini(str)
+#define rosidl_runtime_c__U16String__assignn(str, value, n) rosidl_generator_c__U16String__assignn(str, value, n)
+#define rosidl_runtime_c__U16String__assign(str, value) rosidl_generator_c__U16String__assign(str, value)
+#define rosidl_runtime_c__U16String__assignn_from_char(str, value, n) rosidl_generator_c__U16String__assignn_from_char(str, value, n)
+#define rosidl_runtime_c__U16String__len(value) rosidl_generator_c__U16String__len(value)
+#define rosidl_runtime_c__U16String__resize(str, n) rosidl_generator_c__U16String__resize(str, n)
+#define rosidl_runtime_c__U16String__Sequence__init(sequence, size) rosidl_generator_c__U16String__Sequence__init(sequence, size)
+#define rosidl_runtime_c__U16String__Sequence__fini(sequence) rosidl_generator_c__U16String__Sequence__fini(sequence)
+#define rosidl_runtime_c__U16String__Sequence__create(size) rosidl_generator_c__U16String__Sequence__create(size)
+#define rosidl_runtime_c__U16String__Sequence__destroy(sequence) rosidl_generator_c__U16String__Sequence__destroy(sequence)
+
+#endif
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support.hpp b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support.hpp
new file mode 100644
index 0000000..da558fc
--- /dev/null
+++ b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support.hpp
@@ -0,0 +1,38 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+#include "rosidl_typesupport_protobuf/message_type_support.hpp"
+
+namespace rosidl_typesupport_protobuf
+{
+
+typedef struct service_type_support_t
+{
+ const char * service_namespace;
+ const char * service_name;
+
+ const rosidl_message_type_support_t * request;
+ const rosidl_message_type_support_t * response;
+} service_type_support_t;
+
+}
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support_decl.hpp b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support_decl.hpp
new file mode 100644
index 0000000..854b99f
--- /dev/null
+++ b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support_decl.hpp
@@ -0,0 +1,39 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+//rosidl_service_type_support_t
+#include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp"
+
+namespace rosidl_typesupport_protobuf
+{
+
+/// Get the rosidl service typesupport handler of the type.
+/**
+ * This is implemented in the shared library provided by this package.a
+ * \return The rosidl_service_type_support_t of type T.
+ */
+template
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+const rosidl_service_type_support_t * get_service_type_support_handle();
+
+} // namespace rosidl_typesupport_protobuf_cpp
diff --git a/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/visibility_control.h b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/visibility_control.h
new file mode 100644
index 0000000..ce6940d
--- /dev/null
+++ b/rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/visibility_control.h
@@ -0,0 +1,57 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// This logic was borrowed (then namespaced) from the examples on the gcc wiki:
+// https://gcc.gnu.org/wiki/Visibility
+
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef __GNUC__
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT __attribute__ ((dllexport))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT __attribute__ ((dllimport))
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT __declspec(dllexport)
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT __declspec(dllimport)
+ #endif
+ #ifdef ROSIDL_TYPESUPPORT_PROTOBUF_BUILDING_DLL
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT
+ #endif
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_LOCAL
+#else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT __attribute__ ((visibility("default")))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT
+ #if __GNUC__ >= 4
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC __attribute__ ((visibility("default")))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_LOCAL __attribute__ ((visibility("hidden")))
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_LOCAL
+ #endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/package.xml b/rosidl_typesupport_protobuf/package.xml
new file mode 100644
index 0000000..61066a4
--- /dev/null
+++ b/rosidl_typesupport_protobuf/package.xml
@@ -0,0 +1,16 @@
+
+
+
+ rosidl_typesupport_protobuf
+ 0.0.1
+ Shared code for rosidl_typesupport_protobuf_cpp and rosidl_typesupport_protobuf_c.
+ Aleksandar Brakmić
+ Apache License 2.0
+
+ ament_cmake
+
+
+
+ ament_cmake
+
+
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf/rosidl_typesupport_protobuf/__init__.py b/rosidl_typesupport_protobuf/rosidl_typesupport_protobuf/__init__.py
new file mode 100644
index 0000000..a790484
--- /dev/null
+++ b/rosidl_typesupport_protobuf/rosidl_typesupport_protobuf/__init__.py
@@ -0,0 +1,130 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+import os
+
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_parser import definition
+
+# A postfix for the protobuf package name / the c++ namespace
+PROTO_PACKAGE_POSTFIX = "pb"
+
+DISTROS = {"dashing": 0, "eloquent": 1, "foxy": 2}
+CURRENT_DISTRO_NAME = os.getenv("ROS_DISTRO")
+CURRENT_DISTRO = DISTROS[CURRENT_DISTRO_NAME]
+
+_TYPE_SUPPORT_NAME = ""
+_NAMESPACE_DELIMETER = ""
+
+def set_type_support_name(val):
+ global _TYPE_SUPPORT_NAME
+ _TYPE_SUPPORT_NAME = val
+
+def set_namespace_delimeter(val):
+ global _NAMESPACE_DELIMETER
+ _NAMESPACE_DELIMETER = val
+
+def ros_message_header(package_name, interface_path):
+ include_parts = [package_name] + list(interface_path.parents[0].parts)
+ if CURRENT_DISTRO >= DISTROS["foxy"]:
+ include_parts += ["detail"]
+ include_parts += [convert_camel_case_to_lower_case_underscore(interface_path.stem)]
+ include_base = '/'.join(include_parts)
+
+ return f"{include_base}__struct.hpp"
+
+def ros_message_header_c(package_name, interface_path):
+ include_parts = [package_name] + list(interface_path.parents[0].parts)
+ if CURRENT_DISTRO >= DISTROS["foxy"]:
+ include_parts += ["detail"]
+ include_parts += [convert_camel_case_to_lower_case_underscore(interface_path.stem)]
+ include_base = '/'.join(include_parts)
+
+ return f"{include_base}__struct.h"
+
+def ros_message_functions_header_c(package_name, interface_path):
+ include_parts = [package_name] + list(interface_path.parents[0].parts)
+ if CURRENT_DISTRO >= DISTROS["foxy"]:
+ include_parts += ["detail"]
+ include_parts += [convert_camel_case_to_lower_case_underscore(interface_path.stem)]
+ include_base = '/'.join(include_parts)
+
+ return f"{include_base}__functions.h"
+
+def ros_message_functions_header_c_from_namespace(namespace, name):
+ include_parts = namespace;
+ if CURRENT_DISTRO >= DISTROS["foxy"]:
+ include_parts += ["detail"]
+ include_parts += [convert_camel_case_to_lower_case_underscore(name)]
+ include_base = '/'.join(include_parts)
+
+ return f"{include_base}__functions.h"
+
+def protobuf_message_header(package_name, interface_path):
+ include_parts = [package_name] + list(interface_path.parents[0].parts)
+ include_base = '/'.join(include_parts)
+ include_prefix = interface_path.stem
+
+ return '/'.join(include_parts + [include_prefix + ".pb.h"])
+
+def typesupport_header(package_name, interface_path):
+ include_parts = [package_name] + list(interface_path.parents[0].parts) + [convert_camel_case_to_lower_case_underscore(interface_path.stem)]
+ include_base = '/'.join(include_parts)
+
+ return f"{include_base}__{_TYPE_SUPPORT_NAME}.hpp"
+
+def visibility_control_header(package_name):
+ return f"{package_name}/{_TYPE_SUPPORT_NAME}__visibility_control.h"
+
+def ros_type_namespace(package_name, interface_path):
+ return _NAMESPACE_DELIMETER.join([package_name] + list(interface_path.parents[0].parts))
+
+def ros_type_name(message):
+ return message.structure.namespaced_type.name
+
+def ros_type(package_name, interface_path, message):
+ ros_type_ns = ros_type_namespace(package_name, interface_path)
+ ros_type_nm = ros_type_name(message)
+ return "::" + _NAMESPACE_DELIMETER.join([ros_type_ns, ros_type_nm])
+
+def ros_type_from_namespaced_type(namespaced_type):
+ return "::" + _NAMESPACE_DELIMETER.join(namespaced_type.namespaces + [namespaced_type.name])
+
+def ros_type_from_namespaced_type_c(namespaced_type):
+ return "::" + _NAMESPACE_DELIMETER.join(namespaced_type.namespaces + [namespaced_type.name])
+
+def ros_service_namespace(package_name, interface_path):
+ return _NAMESPACE_DELIMETER.join([package_name] + list(interface_path.parents[0].parts))
+
+def ros_service_name(service):
+ return service.namespaced_type.name
+
+def ros_service_type(package_name, interface_path, service):
+ ros_type_ns = ros_service_namespace(package_name, interface_path)
+ ros_type_nm = ros_service_name(service)
+ return "::" + _NAMESPACE_DELIMETER.join([ros_type_ns, ros_type_nm])
+
+def protobuf_type(package_name, interface_path, message):
+ namespace = "::".join([package_name] + list(interface_path.parents[0].parts))
+ return "::" + "::".join([namespace, PROTO_PACKAGE_POSTFIX, ros_type_name(message)])
+
+def protobuf_type_from_namespaced_type(namespaced_type):
+ return "::" + "::".join(namespaced_type.namespaces + [PROTO_PACKAGE_POSTFIX, namespaced_type.name])
+
+def protobuf_type_from_namespaced_type_c(namespaced_type):
+ return "::" + "::".join(namespaced_type.namespaces + [PROTO_PACKAGE_POSTFIX, namespaced_type.name])
diff --git a/rosidl_typesupport_protobuf_c/CMakeLists.txt b/rosidl_typesupport_protobuf_c/CMakeLists.txt
new file mode 100644
index 0000000..a7e25cd
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/CMakeLists.txt
@@ -0,0 +1,130 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+cmake_minimum_required(VERSION 3.12)
+
+project(rosidl_typesupport_protobuf_c)
+
+if(DEFINED ENV{PROTOBUF_STATIC_DISABLE})
+ set(PROTOBUF_STATIC_DISABLE $ENV{PROTOBUF_STATIC_DISABLE}
+ CACHE BOOL "If Protobuf Static should be disabled.")
+else()
+ set(PROTOBUF_STATIC_DISABLE FALSE
+ CACHE BOOL "If Protobuf Static should be disabled.")
+endif()
+
+# Default to C99
+if(NOT CMAKE_C_STANDARD)
+ set(CMAKE_C_STANDARD 99)
+endif()
+
+# Default to C++14
+if(NOT CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 14)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ add_compile_options(/W4)
+ add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+endif()
+
+find_package(ament_cmake REQUIRED)
+
+if(PROTOBUF_STATIC_DISABLE)
+ ament_package()
+ message(STATUS "protobuf static rmw implementation explicitly disabled - skipping '${PROJECT_NAME}'")
+ return()
+endif()
+
+find_package(rmw REQUIRED)
+find_package(ament_cmake_python REQUIRED)
+find_package(rosidl_typesupport_protobuf REQUIRED)
+find_package(rosidl_generator_c REQUIRED)
+if(${is_foxy_or_greater})
+ find_package(rosidl_runtime_c REQUIRED)
+endif()
+find_package(rosidl_typesupport_introspection_c REQUIRED)
+find_package(rosidl_typesupport_introspection_cpp REQUIRED)
+
+ament_export_dependencies(rmw)
+ament_export_dependencies(rosidl_cmake)
+ament_export_dependencies(rosidl_generator_c)
+if(${is_foxy_or_greater})
+ ament_export_dependencies(rosidl_runtime_c)
+endif()
+ament_export_dependencies(rosidl_typesupport_introspection_c)
+ament_export_dependencies(rosidl_typesupport_introspection_cpp)
+ament_export_dependencies(rosidl_typesupport_interface)
+ament_export_dependencies(rosidl_typesupport_protobuf)
+
+ament_export_include_directories(include)
+
+ament_python_install_package(${PROJECT_NAME})
+
+add_library(${PROJECT_NAME} SHARED
+ src/identifier.cpp
+ src/wstring_conversion.cpp
+ src/to_ros_c_string.cpp
+)
+if(WIN32)
+ target_compile_definitions(${PROJECT_NAME}
+ PRIVATE "ROSIDL_TYPESUPPORT_PROTOBUF_C_BUILDING_DLL")
+endif()
+
+if(${is_foxy_or_greater})
+ ament_target_dependencies(${PROJECT_NAME} "rosidl_typesupport_protobuf" rosidl_runtime_c)
+else()
+ ament_target_dependencies(${PROJECT_NAME} "rosidl_typesupport_protobuf" rosidl_generator_c)
+endif()
+
+target_include_directories(${PROJECT_NAME} PUBLIC include)
+
+ament_export_libraries(${PROJECT_NAME})
+
+ament_target_dependencies(${PROJECT_NAME} rosidl_typesupport_protobuf)
+
+ament_index_register_resource("rosidl_typesupport_c")
+
+ament_package(
+ CONFIG_EXTRAS "cmake/rosidl_typesupport_protobuf_c-extras.cmake.in"
+)
+
+install(
+ PROGRAMS bin/rosidl_typesupport_protobuf_c
+ DESTINATION lib/rosidl_typesupport_protobuf_c
+)
+
+install(
+ DIRECTORY cmake resource
+ DESTINATION share/${PROJECT_NAME}
+)
+
+install(
+ DIRECTORY include/
+ DESTINATION include
+)
+
+install(
+ TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin
+)
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/bin/rosidl_typesupport_protobuf_c b/rosidl_typesupport_protobuf_c/bin/rosidl_typesupport_protobuf_c
new file mode 100644
index 0000000..42ae009
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/bin/rosidl_typesupport_protobuf_c
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+import argparse
+import os
+import sys
+import rosidl_typesupport_protobuf
+
+from rosidl_typesupport_protobuf_c import generate_typesupport_protobuf_c
+
+def is_valid_file(parser, file_name):
+ if not os.path.exists(file_name):
+ parser.error("File does not exist: '{0}'".format(file_name))
+ file_name_abs = os.path.abspath(file_name)
+ if not os.path.isfile(file_name_abs):
+ parser.error("Path exists but is not a file: '{0}'".format(file_name_abs))
+ return file_name
+
+
+def main(argv=sys.argv[1:]):
+ parser = argparse.ArgumentParser(
+ description='Generate the C interfaces for Protobuf.',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument(
+ '--generator-arguments-file',
+ required=True,
+ help='The location of the file containing the generator arguments')
+ args = parser.parse_args(argv)
+
+ rosidl_typesupport_protobuf.set_namespace_delimeter("__")
+ rosidl_typesupport_protobuf.set_type_support_name("rosidl_typesupport_protobuf_c")
+
+ return generate_typesupport_protobuf_c(args.generator_arguments_file)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c-extras.cmake.in b/rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c-extras.cmake.in
new file mode 100644
index 0000000..9a297aa
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c-extras.cmake.in
@@ -0,0 +1,29 @@
+# generated from
+# rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c-extras.cmake.in
+
+find_package(Protobuf REQUIRED)
+
+if(NOT Protobuf_FOUND)
+ message(STATUS "Could not find Protobuf: skipping rosidl_typesupport_protobuf_c")
+else()
+ find_package(ament_cmake_core QUIET REQUIRED)
+ ament_register_extension(
+ "rosidl_generate_idl_interfaces"
+ "rosidl_typesupport_protobuf_c"
+ "rosidl_typesupport_protobuf_c_generate_interfaces.cmake")
+
+ set(rosidl_typesupport_protobuf_c_BIN
+ "${rosidl_typesupport_protobuf_c_DIR}/../../../lib/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c")
+ normalize_path(rosidl_typesupport_protobuf_c_BIN
+ "${rosidl_typesupport_protobuf_c_BIN}")
+
+ set(rosidl_typesupport_protobuf_c_GENERATOR_FILES
+ "${rosidl_typesupport_protobuf_c_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_typesupport_protobuf_c/__init__.py")
+ normalize_path(rosidl_typesupport_protobuf_c_GENERATOR_FILES
+ "${rosidl_typesupport_protobuf_c_GENERATOR_FILES}")
+
+ set(rosidl_typesupport_protobuf_c_TEMPLATE_DIR
+ "${rosidl_typesupport_protobuf_c_DIR}/../resource")
+ normalize_path(rosidl_typesupport_protobuf_c_TEMPLATE_DIR
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}")
+endif()
diff --git a/rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c_generate_interfaces.cmake b/rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c_generate_interfaces.cmake
new file mode 100644
index 0000000..7077c9c
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c_generate_interfaces.cmake
@@ -0,0 +1,185 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+find_package(Protobuf REQUIRED)
+
+find_package(rosidl_adapter_proto REQUIRED)
+find_package(rosidl_typesupport_protobuf REQUIRED)
+
+set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_c/${PROJECT_NAME}")
+set(_generated_files "")
+foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES})
+ get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY)
+ get_filename_component(_parent_folder "${_parent_folder}" NAME)
+ get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE)
+ string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name)
+ list(APPEND _generated_files
+ "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_protobuf_c.hpp"
+ "${_output_path}/${_parent_folder}/detail/${_header_name}__type_support.cpp"
+ )
+endforeach()
+
+set(_dependency_files "")
+set(_dependencies "")
+foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
+ foreach(_idl_file ${${_pkg_name}_IDL_FILES})
+ set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
+ normalize_path(_abs_idl_file "${_abs_idl_file}")
+ list(APPEND _dependency_files "${_abs_idl_file}")
+ list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
+ endforeach()
+endforeach()
+
+set(target_dependencies
+ "${rosidl_typesupport_protobuf_c_BIN}"
+ ${rosidl_typesupport_protobuf_c_GENERATOR_FILES}
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/idl__rosidl_typesupport_protobuf_c.hpp.em"
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/idl__type_support.cpp.em"
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/msg__rosidl_typesupport_protobuf_c.hpp.em"
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/msg__type_support.cpp.em"
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/srv__rosidl_typesupport_protobuf_c.hpp.em"
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/srv__type_support.cpp.em"
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/rosidl_typesupport_protobuf_c__visibility_control.h.in"
+ ${rosidl_generate_interfaces_ABS_IDL_FILES}
+ ${_dependency_files}
+)
+
+set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_c__arguments.json")
+rosidl_write_generator_arguments(
+ "${generator_arguments_file}"
+ PACKAGE_NAME "${PROJECT_NAME}"
+ IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}"
+ ROS_INTERFACE_DEPENDENCIES "${_dependencies}"
+ OUTPUT_DIR "${_output_path}"
+ TEMPLATE_DIR "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}"
+ TARGET_DEPENDENCIES ${target_dependencies}
+)
+
+add_custom_command(
+ OUTPUT ${_generated_files}
+ COMMAND ${PYTHON_EXECUTABLE} ${rosidl_typesupport_protobuf_c_BIN}
+ --generator-arguments-file "${generator_arguments_file}"
+ DEPENDS ${target_dependencies}
+ COMMENT "Generating C type support for Protobuf"
+ VERBATIM
+)
+
+set(_target_suffix "__rosidl_typesupport_protobuf_c")
+
+link_directories(${Protobuf_LIBRARY_DIRS})
+
+add_library(${rosidl_generate_interfaces_TARGET}${_target_suffix} SHARED
+ ${_generated_files}
+ ${rosidl_adapter_proto_GENERATED_CPP}
+)
+
+if(rosidl_generate_interfaces_LIBRARY_NAME)
+ set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PROPERTIES OUTPUT_NAME "${rosidl_generate_interfaces_LIBRARY_NAME}${_target_suffix}")
+endif()
+
+set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PROPERTIES CXX_STANDARD 14
+)
+
+ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ rmw
+ rosidl_typesupport_protobuf
+ rosidl_typesupport_protobuf_c
+ rosidl_typesupport_interface
+)
+
+# Set flag for visibility macro
+if(WIN32)
+ target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PRIVATE "ROSIDL_TYPESUPPORT_PROTOBUF_BUILDING_DLL" "ROSIDL_TYPESUPPORT_PROTOBUF_C_BUILDING_DLL__${PROJECT_NAME}")
+ set (Protobuf_USE_STATIC_LIBS TRUE)
+endif()
+
+if(NOT WIN32)
+ set(_target_compile_flags "-Wall -Wextra -Wpedantic")
+else()
+ set(_target_compile_flags "/W4")
+endif()
+
+string(REPLACE ";" " " _target_compile_flags "${_target_compile_flags}")
+set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PROPERTIES COMPILE_FLAGS "${_target_compile_flags}"
+)
+
+target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PUBLIC
+ ${_output_path}
+ ${Protobuf_INCLUDE_DIR}
+ ${rosidl_adapter_proto_INCLUDE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_c
+ ${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_c
+)
+
+# generate header to switch between export and import for a specific package
+set(_visibility_control_file
+"${_output_path}/rosidl_typesupport_protobuf_c__visibility_control.h")
+string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER)
+configure_file(
+ "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/rosidl_typesupport_protobuf_c__visibility_control.h.in"
+ "${_visibility_control_file}"
+ @ONLY
+)
+
+# Depend on dependencies
+foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
+ ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ${_pkg_name})
+ target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ${${_pkg_name}_LIBRARIES${_target_suffix}})
+endforeach()
+
+target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ${rosidl_generate_interfaces_TARGET}__rosidl_generator_c
+ ${Protobuf_LIBRARY}
+)
+
+add_dependencies(
+ ${rosidl_generate_interfaces_TARGET}
+ ${rosidl_generate_interfaces_TARGET}${_target_suffix}
+)
+
+if(NOT rosidl_generate_interfaces_SKIP_INSTALL)
+ install(
+ DIRECTORY "${_output_path}/"
+ DESTINATION "include/${PROJECT_NAME}"
+ PATTERN "*.cpp" EXCLUDE
+ )
+
+ if(NOT _generated_files STREQUAL "")
+ ament_export_include_directories(include)
+ endif()
+
+ install(
+ TARGETS ${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin
+ )
+
+ rosidl_export_typesupport_libraries(${_target_suffix}
+ ${rosidl_generate_interfaces_TARGET}${_target_suffix})
+
+ ament_export_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix})
+endif()
diff --git a/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/identifier.hpp b/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/identifier.hpp
new file mode 100644
index 0000000..6e93c1b
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/identifier.hpp
@@ -0,0 +1,30 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+namespace rosidl_typesupport_protobuf_c
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT
+extern const char *identifier;
+
+} // namespace rosidl_typesupport_protobuf_cpp
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/to_ros_c_string.hpp b/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/to_ros_c_string.hpp
new file mode 100644
index 0000000..ebd741e
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/to_ros_c_string.hpp
@@ -0,0 +1,33 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+#include "rosidl_typesupport_protobuf/visibility_control.h"
+#include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp"
+
+namespace typesupport_protobuf_c
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+void to_ros_c_string(const std::string &str, rosidl_runtime_c__String &ros_str);
+
+}
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/wstring_conversion.hpp b/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/wstring_conversion.hpp
new file mode 100644
index 0000000..c6db489
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/wstring_conversion.hpp
@@ -0,0 +1,36 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+#include "rosidl_typesupport_protobuf/visibility_control.h"
+#include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp"
+
+namespace rosidl_typesupport_protobuf_c
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+void write_to_string(const rosidl_runtime_c__U16String &u16str, std::string &str);
+
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+void write_to_u16string(const std::string &str, rosidl_runtime_c__U16String &u16str);
+
+}
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/package.xml b/rosidl_typesupport_protobuf_c/package.xml
new file mode 100644
index 0000000..d52b0ea
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/package.xml
@@ -0,0 +1,35 @@
+
+
+
+ rosidl_typesupport_protobuf_c
+ 0.0.1
+ Generate the C interfaces for Protobuf.
+ Aleksandar Brakmić
+ Apache License 2.0
+
+ ament_cmake
+ rosidl_cmake
+ rosidl_generator_c
+ rosidl_adapter_proto
+ rosidl_typesupport_protobuf
+
+ ament_cmake
+ rosidl_cmake
+ rosidl_adapter_proto
+ rosidl_generator_c
+ rosidl_typesupport_protobuf
+
+ rmw
+
+ rosidl_parser
+ rosidl_typesupport_interface
+
+ ament_lint_auto
+ ament_lint_common
+
+ rosidl_typesupport_c_packages
+
+
+ ament_cmake
+
+
diff --git a/rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em b/rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em
new file mode 100644
index 0000000..3051145
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em
@@ -0,0 +1,92 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+// generated from rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em
+// with input from @(package_name):@(interface_path)
+// generated code does not contain a copyright notice
+@
+@#######################################################################
+@# EmPy template for generating __rosidl_typesupport_protobuf_c.hpp files
+@#
+@# Context:
+@# - package_name (string)
+@# - interface_path (Path relative to the directory named after the package)
+@# - content (IdlContent, list of elements, e.g. Messages or Services)
+@#######################################################################
+@
+#pragma once
+
+@{
+
+include_directives = set()
+
+#######################################################################
+# Handle message
+#######################################################################
+from rosidl_parser.definition import Message
+for message in content.get_elements_of_type(Message):
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=message,
+ include_directives=include_directives)
+
+#######################################################################
+# Handle service
+#######################################################################
+from rosidl_parser.definition import Service
+for service in content.get_elements_of_type(Service):
+ TEMPLATE(
+ 'srv__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ service=service,
+ include_directives=include_directives)
+
+#######################################################################
+# Handle action
+#######################################################################
+from rosidl_parser.definition import Action
+for action in content.get_elements_of_type(Action):
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.goal,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.result,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'srv__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.send_goal_service,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'srv__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.get_result_service,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback_message,
+ include_directives=include_directives)
+}@
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em b/rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em
new file mode 100644
index 0000000..ea6864d
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em
@@ -0,0 +1,121 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+// generated from rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em
+// with input from @(package_name):@(interface_path)
+// generated code does not contain a copyright notice
+@
+@#######################################################################
+@# EmPy template for generating __type_support.cpp files
+@#
+@# Context:
+@# - package_name (string)
+@# - interface_path (Path relative to the directory named after the package)
+@# - content (IdlContent, list of elements, e.g. Messages or Services)
+@#######################################################################
+@
+@{
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_typesupport_protobuf import *
+
+include_directives = set()
+forward_declared_types = set()
+
+system_header_files = []
+header_files = [
+ typesupport_header(package_name, interface_path),
+ ros_message_header_c(package_name, interface_path),
+ ros_message_functions_header_c(package_name, interface_path)
+]
+
+}@
+
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+
+#######################################################################
+# Handle message
+#######################################################################
+from rosidl_parser.definition import Message
+for message in content.get_elements_of_type(Message):
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+
+#######################################################################
+# Handle service
+#######################################################################
+from rosidl_parser.definition import Service
+for service in content.get_elements_of_type(Service):
+ TEMPLATE(
+ 'srv__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ service=service,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+
+#######################################################################
+# Handle action
+#######################################################################
+from rosidl_parser.definition import Action
+for action in content.get_elements_of_type(Action):
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.goal,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.result,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'srv__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.send_goal_service,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'srv__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.get_result_service,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback_message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+}@
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/resource/msg__rosidl_typesupport_protobuf_c.hpp.em b/rosidl_typesupport_protobuf_c/resource/msg__rosidl_typesupport_protobuf_c.hpp.em
new file mode 100644
index 0000000..5bc5342
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/msg__rosidl_typesupport_protobuf_c.hpp.em
@@ -0,0 +1,85 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@# Included from rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em
+@{
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_typesupport_protobuf import *
+
+system_header_files = [
+ "string"
+]
+
+header_files = [
+ "rosidl_typesupport_cpp/message_type_support.hpp",
+ ros_message_header_c(package_name, interface_path),
+ ros_message_header(package_name, interface_path),
+ visibility_control_header(package_name),
+ "rosidl_typesupport_interface/macros.h",
+ protobuf_message_header(package_name, interface_path)
+]
+
+ros_type_ns = ros_type_namespace(package_name, interface_path)
+ros_type_name = ros_type_name(message)
+ros_type = ros_type(package_name, interface_path, message)
+proto_type = protobuf_type(package_name, interface_path, message)
+
+}@
+
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@[for ns in message.structure.namespaced_type.namespaces]@
+namespace @(ns)
+{
+@[end for]@
+namespace typesupport_protobuf_c
+{
+
+bool
+ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name)
+convert_to_proto(const @(ros_type) &ros_msg, @(proto_type) &pb_msg);
+
+bool
+ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name)
+convert_to_ros(const @(proto_type) &pb_msg, @(ros_type) &ros_msg);
+
+} // namespace typesupport_protobuf_c
+@[ for ns in reversed(message.structure.namespaced_type.namespaces)]@
+} // namespace @(ns)
+@[ end for]@
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name)
+const rosidl_message_type_support_t *
+ ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(ros_type_ns.replace("__", ", ")), @(ros_type_name))();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_c/resource/msg__type_support.cpp.em b/rosidl_typesupport_protobuf_c/resource/msg__type_support.cpp.em
new file mode 100644
index 0000000..2815849
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/msg__type_support.cpp.em
@@ -0,0 +1,338 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@# Included from rosidl_typesupport_protobuf_c/resource/idl__type_support.c.em
+@{
+import rosidl_parser.parser as rosidl
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_parser.definition import *
+from rosidl_typesupport_protobuf import *
+
+ros_type_ns = ros_type_namespace(package_name, interface_path)
+ros_type_name = ros_type_name(message)
+ros_type = ros_type(package_name, interface_path, message)
+proto_type = protobuf_type(package_name, interface_path, message)
+
+system_header_files = [
+ 'string',
+ 'algorithm'
+]
+
+header_files = [
+ 'rosidl_typesupport_cpp/message_type_support.hpp',
+ visibility_control_header(package_name),
+ 'rosidl_typesupport_protobuf_c/identifier.hpp',
+ 'rosidl_typesupport_protobuf_c/to_ros_c_string.hpp',
+ 'rosidl_typesupport_protobuf_c/wstring_conversion.hpp',
+ 'rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp',
+ 'rosidl_typesupport_protobuf/message_type_support.hpp',
+ 'rosidl_typesupport_protobuf/message_type_support_decl.hpp',
+ 'rosidl_typesupport_protobuf/proto_descriptor_helper.hpp',
+ protobuf_message_header(package_name, interface_path)
+]
+
+for member in message.structure.members:
+ keys = set([])
+ type_ = member.type
+
+ if isinstance(type_, AbstractNestedType):
+ type_ = type_.value_type
+ if isinstance(type_, NamespacedType):
+ if (
+ type_.name.endswith(ACTION_GOAL_SUFFIX) or
+ type_.name.endswith(ACTION_RESULT_SUFFIX) or
+ type_.name.endswith(ACTION_FEEDBACK_SUFFIX)
+ ):
+ typename = type_.name.rsplit('_', 1)[0]
+ else:
+ typename = type_.name
+
+ keys.add(ros_message_functions_header_c_from_namespace(type_.namespaces, typename))
+
+ for key in keys:
+ header_files.append(key)
+
+ header_files.sort();
+
+}@
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+TEMPLATE(
+ 'tmpl_forward_declarations.em',
+ message=message,
+ forward_declared_types=forward_declared_types
+)
+}@
+@[ for ns in message.structure.namespaced_type.namespaces]@
+namespace @(ns)
+{
+@[ end for]@
+namespace typesupport_protobuf_c
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name)
+bool convert_to_proto(const @(ros_type) &ros_msg, @(proto_type) &pb_msg)
+{
+@[for member in message.structure.members]@
+ // Member: @(member.name)
+@[ if isinstance(member.type, AbstractNestedType)]@
+@[ if isinstance(member.type, Array)]@
+@[ if isinstance(member.type.value_type, BasicType)]@
+ *pb_msg.mutable_@(member.name)() = { std::begin(ros_msg.@(member.name)), std::end(ros_msg.@(member.name)) };
+@[ elif isinstance(member.type.value_type, AbstractString)]@
+ for(auto &data : ros_msg.@(member.name))
+ {
+ auto &str{*pb_msg.add_@(member.name)()};
+ str = data.data;
+ }
+@[ elif isinstance(member.type.value_type, AbstractWString)]@
+ for(auto &data : ros_msg.@(member.name))
+ {
+ auto &str{*pb_msg.add_@(member.name)()};
+ ::rosidl_typesupport_protobuf_c::write_to_string(data, str);
+ }
+@[ elif isinstance(member.type.value_type, NamespacedType)]@
+ for(auto &data : ros_msg.@(member.name))
+ {
+ auto ptr{pb_msg.add_@(member.name)()};
+ @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_c::convert_to_proto(data, *ptr);
+ }
+@[ end if]@
+@[ elif isinstance(member.type, AbstractSequence)]@
+ {
+ auto size{ros_msg.@(member.name).size};
+ auto data{ros_msg.@(member.name).data};
+ auto arr_ptr{pb_msg.mutable_@(member.name)()};
+@[ if isinstance(member.type.value_type, BasicType)]@
+@{is_string = member.type.value_type.typename in [*CHARACTER_TYPES, OCTET_TYPE, 'uint8', 'int8']}@
+@[ if is_string]@
+ arr_ptr->insert(arr_ptr->end(), data, data + size);
+@[ else]
+ arr_ptr->Reserve(size);
+ for(size_t i{0}; i < size; i++)
+ {
+ arr_ptr->AddAlreadyReserved(data[i]);
+ }
+@[ end if]@
+@[ elif isinstance(member.type.value_type, AbstractString)]@
+ arr_ptr->Reserve(size);
+ for(size_t i{0}; i < size; i++)
+ {
+ arr_ptr->Add({data[i].data, data[i].size});
+ }
+@[ elif isinstance(member.type.value_type, AbstractWString)]@
+ arr_ptr->Reserve(size);
+ for(size_t i{0}; i < size; i++)
+ {
+ ::rosidl_typesupport_protobuf_c::write_to_string(data[i], *arr_ptr->Add());
+ }
+@[ elif isinstance(member.type.value_type, NamespacedType)]@
+ arr_ptr->Reserve(size);
+ for(size_t i{0}; i < size; i++)
+ {
+ auto obj{arr_ptr->Add()};
+ @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_c::convert_to_proto(data[i], *obj);
+ }
+@[ end if]@
+ }
+@[ end if]@
+@[ elif isinstance(member.type, BasicType)]@
+ pb_msg.set_@(member.name)(ros_msg.@(member.name));
+@[ elif isinstance(member.type, AbstractString)]@
+ pb_msg.set_@(member.name)(ros_msg.@(member.name).data);
+@[ elif isinstance(member.type, AbstractWString)]@
+ ::rosidl_typesupport_protobuf_c::write_to_string(ros_msg.@(member.name), *pb_msg.mutable_@(member.name)());
+@[ elif isinstance(member.type, NamespacedType)]@
+ @("::" + "::".join(member.type.namespaces))::typesupport_protobuf_c::convert_to_proto(ros_msg.@(member.name), *pb_msg.mutable_@(member.name)());
+@[ end if]@
+@[end for]@
+
+ return true;
+}
+
+ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name)
+bool convert_to_ros(const @(proto_type) &pb_msg, @(ros_type) &ros_msg)
+{
+@[for member in message.structure.members]@
+ // Member: @(member.name)
+@[ if isinstance(member.type, AbstractNestedType)]@
+@[ if isinstance(member.type, Array)]@
+ {
+ auto &pb_arr{pb_msg.@(member.name)()};
+
+@[ if isinstance(member.type.value_type, BasicType)]@
+ std::copy(pb_arr.begin(), pb_arr.end(), ros_msg.@(member.name));
+@[ elif isinstance(member.type.value_type, AbstractString)]@
+ for(size_t i{0}; i < sizeof(ros_msg.@(member.name))/sizeof(ros_msg.@(member.name)[0]); i++)
+ {
+ ::typesupport_protobuf_c::to_ros_c_string(pb_arr[i], ros_msg.@(member.name)[i]);
+ }
+@[ elif isinstance(member.type.value_type, AbstractWString)]@
+ for(size_t i{0}; i < sizeof(ros_msg.@(member.name))/sizeof(ros_msg.@(member.name)[0]); i++)
+ {
+ ::rosidl_typesupport_protobuf_c::write_to_u16string(pb_arr[i], ros_msg.@(member.name)[i]);
+ }
+@[ elif isinstance(member.type.value_type, NamespacedType)]@
+ for(size_t i{0}; i < sizeof(ros_msg.@(member.name))/sizeof(ros_msg.@(member.name)[0]); i++)
+ {
+ @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_c::convert_to_ros(pb_arr[i], ros_msg.@(member.name)[i]);
+ }
+@[ end if]@
+ }
+@[ elif isinstance(member.type, AbstractSequence)]@
+@{
+value_type_ = member.type.value_type
+if isinstance(value_type_, AbstractString):
+ array_init = 'rosidl_runtime_c__String__Sequence__init'
+ array_fini = 'rosidl_runtime_c__String__Sequence__fini'
+elif isinstance(value_type_, AbstractWString):
+ array_init = 'rosidl_runtime_c__U16String__Sequence__init'
+ array_fini = 'rosidl_runtime_c__U16String__Sequence__fini'
+elif isinstance(value_type_, BasicType):
+ type_ = value_type_.typename
+ type_ = type_.replace(' ', '_')
+ array_init = 'rosidl_runtime_c__{type_}__Sequence__init'.format(**locals())
+ array_fini = 'rosidl_runtime_c__{type_}__Sequence__fini'.format(**locals())
+else:
+ type_ = value_type_
+ array_init = '__'.join(type_.namespaced_name()) + '__Sequence__init'
+ array_fini = '__'.join(type_.namespaced_name()) + '__Sequence__fini'
+}@
+ {
+ auto &pb_arr{pb_msg.@(member.name)()};
+ auto size{pb_arr.size()};
+
+ @(array_init)(&ros_msg.@(member.name), size);
+ auto ros_arr{ros_msg.@(member.name).data};
+
+@[ if isinstance(member.type.value_type, BasicType)]@
+ std::copy(pb_arr.begin(), pb_arr.end(), ros_arr);
+@[ elif isinstance(member.type.value_type, AbstractString)]@
+ for(int i{0}; i < size; i++)
+ {
+ ::typesupport_protobuf_c::to_ros_c_string(pb_arr[i], ros_arr[i]);
+ }
+@[ elif isinstance(member.type.value_type, AbstractWString)]@
+ for(int i{0}; i < size; i++)
+ {
+ ::rosidl_typesupport_protobuf_c::write_to_u16string(pb_arr[i], ros_arr[i]);
+ }
+@[ elif isinstance(member.type.value_type, NamespacedType)]@
+ for(int i{0}; i < size; i++)
+ {
+ @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_c::convert_to_ros(pb_arr[i], ros_arr[i]);
+ }
+@[ end if]@
+ }
+@[ end if]@
+@[ elif isinstance(member.type, BasicType)]@
+ ros_msg.@(member.name) = pb_msg.@(member.name)();
+@[ elif isinstance(member.type, AbstractString)]@
+ ::typesupport_protobuf_c::to_ros_c_string(pb_msg.@(member.name)(), ros_msg.@(member.name));
+@[ elif isinstance(member.type, AbstractWString)]@
+ ::rosidl_typesupport_protobuf_c::write_to_u16string(pb_msg.@(member.name)(), ros_msg.@(member.name));
+@[ elif isinstance(member.type, NamespacedType)]@
+ @("::" + "::".join(member.type.namespaces))::typesupport_protobuf_c::convert_to_ros(pb_msg.@(member.name)(), ros_msg.@(member.name));
+@[ end if]@
+@[end for]@
+
+ return true;
+}
+
+static bool _@(ros_type_name)__serialize(const void *untyped_ros_msg, std::string &serialized_msg)
+{
+ @(proto_type) pb_msg{};
+ auto ros_msg{static_cast(untyped_ros_msg)};
+
+ convert_to_proto(*ros_msg, pb_msg);
+ return pb_msg.SerializeToString(&serialized_msg);
+}
+
+static bool _@(ros_type_name)__deserialize(void *untyped_ros_msg, const void *serialized_msg, size_t size)
+{
+ @(proto_type) pb_msg{};
+ auto ros_msg{static_cast<@(ros_type) *>(untyped_ros_msg)};
+
+ pb_msg.ParseFromArray(serialized_msg, size);
+ return convert_to_ros(pb_msg, *ros_msg);
+}
+
+static std::string _@(ros_type_name)__get_descriptor()
+{
+ return "";
+ return GetProtoMessageDescription<@(proto_type)>();
+}
+
+@{type_support_name = "_" + ros_type_name + "__type_support"}@
+static rosidl_typesupport_protobuf::message_type_support_t @(type_support_name) = {
+ "@(ros_type_ns.replace("__", "::"))",
+ "@(ros_type_name)",
+ _@(ros_type_name)__serialize,
+ _@(ros_type_name)__deserialize,
+ _@(ros_type_name)__get_descriptor
+};
+
+@{
+handle_name = "_" + ros_type_name + "__handle"
+namespaced_handle_name = "::".join([ros_type_ns.replace("__", "::"), "typesupport_protobuf_c", handle_name])
+}@
+static rosidl_message_type_support_t @(handle_name) = {
+ rosidl_typesupport_protobuf_c::identifier,
+ &@(type_support_name),
+ get_message_typesupport_handle_function
+};
+
+} // namespace typesupport_protobuf_c
+@[ for ns in reversed(message.structure.namespaced_type.namespaces)]@
+} // namespace @(ns)
+@[ end for]@
+
+namespace rosidl_typesupport_protobuf
+{
+
+template<>
+ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@(package_name)
+const rosidl_message_type_support_t *get_message_type_support_handle<@(ros_type)>()
+{
+ return &@(namespaced_handle_name);
+}
+
+} // namespace rosidl_typesupport_protobuf
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(ros_type_ns.replace("__", ", ")), @(ros_type_name))() {
+ return &@(namespaced_handle_name);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_c/resource/rosidl_typesupport_protobuf_c__visibility_control.h.in b/rosidl_typesupport_protobuf_c/resource/rosidl_typesupport_protobuf_c__visibility_control.h.in
new file mode 100644
index 0000000..4a62e64
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/rosidl_typesupport_protobuf_c__visibility_control.h.in
@@ -0,0 +1,42 @@
+// generated from
+// rosidl_typesupport_protobuf/rosidl_typesupport_protobuf_cpp/resource/visibility_control.h.in
+// generated code does not contain a copyright notice
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// This logic was borrowed (then namespaced) from the examples on the gcc wiki:
+// https://gcc.gnu.org/wiki/Visibility
+
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef __GNUC__
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@ __attribute__ ((dllexport))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@ __attribute__ ((dllimport))
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@ __declspec(dllexport)
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@ __declspec(dllimport)
+ #endif
+ #ifdef ROSIDL_TYPESUPPORT_PROTOBUF_C_BUILDING_DLL__@PROJECT_NAME@
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@
+ #endif
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_LOCAL__@PROJECT_NAME@
+#else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@ __attribute__ ((visibility("default")))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@
+ #if __GNUC__ >= 4
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@ __attribute__ ((visibility("default")))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_LOCAL__@PROJECT_NAME@ __attribute__ ((visibility("hidden")))
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_C_LOCAL__@PROJECT_NAME@
+ #endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/resource/srv__rosidl_typesupport_protobuf_c.hpp.em b/rosidl_typesupport_protobuf_c/resource/srv__rosidl_typesupport_protobuf_c.hpp.em
new file mode 100644
index 0000000..e6cce60
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/srv__rosidl_typesupport_protobuf_c.hpp.em
@@ -0,0 +1,49 @@
+@# Included from rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em
+@{
+system_header_files = []
+header_files = [
+ 'rmw/types.h',
+ 'rosidl_typesupport_cpp/service_type_support.hpp',
+ 'rosidl_typesupport_interface/macros.h',
+ 'rosidl_typesupport_protobuf/visibility_control.h',
+]
+}@
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.request_message,
+ include_directives=include_directives)
+}@
+
+@{
+TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_c.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.response_message,
+ include_directives=include_directives)
+}@
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+const rosidl_service_type_support_t *
+ ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name])))();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_c/resource/srv__type_support.cpp.em b/rosidl_typesupport_protobuf_c/resource/srv__type_support.cpp.em
new file mode 100644
index 0000000..9e7e50a
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/srv__type_support.cpp.em
@@ -0,0 +1,116 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@# Included from rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em
+@{
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_typesupport_protobuf import ros_service_name, ros_service_namespace, ros_service_type
+
+system_header_files = []
+header_files = [
+ 'rmw/error_handling.h',
+ 'rosidl_typesupport_protobuf_c/identifier.hpp',
+ 'rosidl_typesupport_protobuf/service_type_support.hpp',
+ 'rosidl_typesupport_protobuf/service_type_support_decl.hpp',
+]
+
+service_name = ros_service_name(service)
+service_namespace = ros_service_namespace(package_name, interface_path)
+service_type = ros_service_type(package_name, interface_path, service)
+
+}@
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files = system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.request_message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+}@
+@{
+TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.response_message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+}@
+
+@[for ns in service.namespaced_type.namespaces]@
+namespace @(ns)
+{
+@[end for]@
+namespace typesupport_protobuf_c
+{
+
+static rosidl_typesupport_protobuf::service_type_support_t _@(service.namespaced_type.name)__callbacks = {
+ "@(service_namespace.replace("__", "::"))",
+ "@(service_name)",
+ ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Request)(),
+ ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Response)(),
+};
+
+static rosidl_service_type_support_t _@(service.namespaced_type.name)__handle = {
+ rosidl_typesupport_protobuf_c::identifier,
+ &_@(service_name)__callbacks,
+ get_service_typesupport_handle_function,
+};
+
+} // namespace typesupport_protobuf_c
+@[for ns in reversed(service.namespaced_type.namespaces)]@
+} // namespace @(ns)
+@[end for]@
+
+namespace rosidl_typesupport_protobuf
+{
+
+template<>
+ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT
+const rosidl_service_type_support_t *
+get_service_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name]))>()
+{
+ return &@('::'.join([package_name] + list(interface_path.parents[0].parts)))::typesupport_protobuf_c::_@(service.namespaced_type.name)__handle;
+}
+
+} // namespace rosidl_typesupport_protobuf_c
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+const rosidl_service_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))() {
+ return &@('::'.join([package_name] + list(interface_path.parents[0].parts)))::typesupport_protobuf_c::_@(service.namespaced_type.name)__handle;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_c/resource/tmpl_forward_declarations.em b/rosidl_typesupport_protobuf_c/resource/tmpl_forward_declarations.em
new file mode 100644
index 0000000..16880f8
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/tmpl_forward_declarations.em
@@ -0,0 +1,74 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+from rosidl_parser.definition import *
+from rosidl_typesupport_protobuf import PROTO_PACKAGE_POSTFIX, ros_type_from_namespaced_type, ros_type_from_namespaced_type_c, protobuf_type_from_namespaced_type, protobuf_type_from_namespaced_type_c
+
+def isNamespacedType(type_):
+ from rosidl_parser.definition import NamespacedType
+ return isinstance(type_, NamespacedType)
+
+def isNamespacedArrayType(type_):
+ from rosidl_parser.definition import AbstractNestedType
+ from rosidl_parser.definition import NamespacedType
+ return isinstance(type_, AbstractNestedType) and isinstance(type_.value_type, NamespacedType)
+
+def isTypeAlreadyDeclared(type_, fw_declared_types):
+ from rosidl_typesupport_protobuf import ros_type_from_namespaced_type
+ return ros_type_from_namespaced_type(type_) in fw_declared_types
+
+def registerDeclaredType(type_, fw_declared_types):
+ from rosidl_typesupport_protobuf import ros_type_from_namespaced_type
+ fw_declared_types.add(ros_type_from_namespaced_type(type_))
+
+types_to_declare = list()
+for member in message.structure.members:
+ if isNamespacedType(member.type) and not isTypeAlreadyDeclared(member.type, forward_declared_types):
+ types_to_declare.append(member.type)
+ registerDeclaredType(member.type, forward_declared_types)
+ elif isNamespacedArrayType(member.type) and not isTypeAlreadyDeclared(member.type.value_type, forward_declared_types):
+ types_to_declare.append(member.type.value_type)
+ registerDeclaredType(member.type.value_type, forward_declared_types)
+}@
+@[if len(types_to_declare) > 0]@
+// forward declaration of message dependencies and their conversion functions
+@[end if]@
+@[for type_ in types_to_declare]@
+@{
+ros_type = ros_type_from_namespaced_type_c(type_)
+proto_type = protobuf_type_from_namespaced_type_c(type_)
+}@
+
+@[ for ns in type_.namespaces]@
+namespace @(ns)
+{
+@[ end for]@
+namespace typesupport_protobuf_c
+{
+
+bool convert_to_proto(const @(ros_type)&, @(proto_type)&);
+bool convert_to_ros(const @(proto_type)&, @(ros_type)&);
+
+} // namespace typesupport_protobuf_cpp
+@[ for ns in reversed(type_.namespaces)]@
+} // namespace @(ns)
+@[ end for]@
+
+@[end for]@
diff --git a/rosidl_typesupport_protobuf_c/resource/tmpl_include_directories.em b/rosidl_typesupport_protobuf_c/resource/tmpl_include_directories.em
new file mode 100644
index 0000000..0923243
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/resource/tmpl_include_directories.em
@@ -0,0 +1,47 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+def is_protobuf_header(header_file):
+ header_file.endswith(".pb.h")
+}
+@[for header_file in system_header_files]@
+@[ if header_file not in include_directives]@
+@{include_directives.add(header_file)}@
+#include <@(header_file)>
+@[ end if]@
+@[end for]@
+
+@[for header_file in header_files]@
+@[ if header_file not in include_directives]@
+@{include_directives.add(header_file)}@
+@[ if is_protobuf_header(header_file)]@
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4127 4146 4800)
+#endif
+#include "@(header_file)"
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+@[ else]@
+#include "@(header_file)"
+@[ end if]@
+@[ end if]@
+@[end for]@
diff --git a/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/__init__.py b/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/__init__.py
new file mode 100644
index 0000000..1be76da
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/__init__.py
@@ -0,0 +1,26 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+from rosidl_cmake import generate_files
+
+def generate_typesupport_protobuf_c(generator_arguments_file):
+ mapping = {
+ 'idl__rosidl_typesupport_protobuf_c.hpp.em': '%s__rosidl_typesupport_protobuf_c.hpp',
+ 'idl__type_support.cpp.em': 'detail/%s__type_support.cpp',
+ }
+ generate_files(generator_arguments_file, mapping)
diff --git a/rosidl_typesupport_protobuf_c/src/identifier.cpp b/rosidl_typesupport_protobuf_c/src/identifier.cpp
new file mode 100644
index 0000000..24c42e4
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/src/identifier.cpp
@@ -0,0 +1,29 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#include
+
+namespace rosidl_typesupport_protobuf_c
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT
+const char *identifier = "rosidl_typesupport_protobuf_c";
+
+} // namespace rosidl_typesupport_protobuf_cpp
+
diff --git a/rosidl_typesupport_protobuf_c/src/to_ros_c_string.cpp b/rosidl_typesupport_protobuf_c/src/to_ros_c_string.cpp
new file mode 100644
index 0000000..29e31f3
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/src/to_ros_c_string.cpp
@@ -0,0 +1,32 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include "rosidl_typesupport_protobuf_c/to_ros_c_string.hpp"
+
+namespace typesupport_protobuf_c
+{
+
+void to_ros_c_string(const std::string &str, rosidl_runtime_c__String &ros_str)
+{
+ rosidl_runtime_c__String__assignn(&ros_str, &str[0], str.size());
+}
+
+}
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_c/src/wstring_conversion.cpp b/rosidl_typesupport_protobuf_c/src/wstring_conversion.cpp
new file mode 100644
index 0000000..fca0bd5
--- /dev/null
+++ b/rosidl_typesupport_protobuf_c/src/wstring_conversion.cpp
@@ -0,0 +1,46 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include "rosidl_typesupport_protobuf_c/wstring_conversion.hpp"
+
+#include
+
+namespace rosidl_typesupport_protobuf_c
+{
+
+void write_to_string(const rosidl_runtime_c__U16String &u16str, std::string &str)
+{
+ auto data_size = u16str.size * sizeof(decltype(*u16str.data));
+ str.resize(data_size);
+ auto str_start = &str[0];
+ std::memcpy(str_start, u16str.data, data_size);
+}
+
+void write_to_u16string(const std::string &str, rosidl_runtime_c__U16String &u16str)
+{
+ auto data_size = str.size();
+ auto u16str_size = str.size() / sizeof(decltype(*u16str.data));
+ rosidl_runtime_c__U16String__resize(&u16str, u16str_size);
+ auto wstr_start = u16str.data;
+ std::memcpy(wstr_start, str.data(), data_size);
+}
+
+}
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/CMakeLists.txt b/rosidl_typesupport_protobuf_cpp/CMakeLists.txt
new file mode 100644
index 0000000..d7697aa
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/CMakeLists.txt
@@ -0,0 +1,107 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+cmake_minimum_required(VERSION 3.12)
+
+project(rosidl_typesupport_protobuf_cpp)
+
+if(DEFINED ENV{PROTOBUF_STATIC_DISABLE})
+ set(PROTOBUF_STATIC_DISABLE $ENV{PROTOBUF_STATIC_DISABLE}
+ CACHE BOOL "If Protobuf Static should be disabled.")
+else()
+ set(PROTOBUF_STATIC_DISABLE FALSE
+ CACHE BOOL "If Protobuf Static should be disabled.")
+endif()
+
+if(NOT CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 14)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ add_compile_options(/W4)
+ add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+endif()
+
+find_package(ament_cmake REQUIRED)
+if(PROTOBUF_STATIC_DISABLE)
+ ament_package()
+ message(STATUS "Protobuf static typesupport implementation explicitly disabled - skipping '${PROJECT_NAME}'")
+ return()
+endif()
+
+find_package(ament_cmake_python REQUIRED)
+find_package(rosidl_typesupport_protobuf REQUIRED)
+find_package(rosidl_generator_c REQUIRED)
+
+ament_export_dependencies(rmw)
+ament_export_dependencies(rcutils)
+ament_export_dependencies(rosidl_cmake)
+ament_export_dependencies(rosidl_generator_c)
+ament_export_dependencies(rosidl_generator_cpp)
+ament_export_dependencies(rosidl_typesupport_interface)
+ament_export_dependencies(rosidl_typesupport_protobuf)
+
+ament_export_include_directories(include)
+
+ament_python_install_package(${PROJECT_NAME})
+
+add_library(${PROJECT_NAME} SHARED
+ src/identifier.cpp
+ src/wstring_conversion.cpp)
+
+if(WIN32)
+ target_compile_definitions(${PROJECT_NAME}
+ PRIVATE "ROSIDL_TYPESUPPORT_PROTOBUF_CPP_BUILDING_DLL")
+endif()
+
+target_include_directories(${PROJECT_NAME}
+ PUBLIC include
+)
+
+ament_target_dependencies(${PROJECT_NAME} rosidl_typesupport_protobuf)
+
+ament_export_libraries(${PROJECT_NAME})
+
+ament_index_register_resource("rosidl_typesupport_cpp")
+
+ament_package(CONFIG_EXTRAS "cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in")
+
+install(
+ PROGRAMS bin/rosidl_typesupport_protobuf_cpp
+ DESTINATION lib/rosidl_typesupport_protobuf_cpp
+)
+
+install(
+ DIRECTORY cmake resource
+ DESTINATION share/${PROJECT_NAME}
+)
+
+install(
+ DIRECTORY include/
+ DESTINATION include
+)
+
+install(
+ TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin
+)
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/bin/rosidl_typesupport_protobuf_cpp b/rosidl_typesupport_protobuf_cpp/bin/rosidl_typesupport_protobuf_cpp
new file mode 100644
index 0000000..c8f50a5
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/bin/rosidl_typesupport_protobuf_cpp
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+import argparse
+import sys
+import pathlib
+import os
+import rosidl_typesupport_protobuf
+
+from rosidl_cmake import read_generator_arguments
+from rosidl_typesupport_protobuf_cpp import generate_cpp
+
+def main(argv=sys.argv[1:]):
+ parser = argparse.ArgumentParser(
+ description='Generate the Protobuf & C++ interfaces for Protobuf type support.',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument(
+ '--generator-arguments-file',
+ required=True,
+ help='The location of the file containing the generator arguments')
+
+ args = parser.parse_args(argv)
+ rosidl_typesupport_protobuf.set_namespace_delimeter("::")
+ rosidl_typesupport_protobuf.set_type_support_name("rosidl_typesupport_protobuf_cpp")
+ # Generate typesupport cpp files
+ rc = generate_cpp(args.generator_arguments_file)
+
+ return rc
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in b/rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in
new file mode 100644
index 0000000..fc06bc4
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in
@@ -0,0 +1,32 @@
+# generated from
+# rosidl_typesupport_protobuf_cpp/
+# rosidl_typesupport_protobuf_cpp-extras.cmake.in
+
+find_package(Protobuf REQUIRED)
+
+if(NOT Protobuf_FOUND)
+ message(STATUS
+ "Could not find Protobuf - skip rosidl_typesupport_protobuf_cpp"
+ )
+else()
+ find_package(ament_cmake_core QUIET REQUIRED)
+ ament_register_extension(
+ "rosidl_generate_idl_interfaces"
+ "rosidl_typesupport_protobuf_cpp"
+ "rosidl_typesupport_protobuf_cpp_generate_interfaces.cmake")
+
+ set(rosidl_typesupport_protobuf_cpp_BIN
+ "${rosidl_typesupport_protobuf_cpp_DIR}/../../../lib/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp")
+ normalize_path(rosidl_typesupport_protobuf_cpp_BIN
+ "${rosidl_typesupport_protobuf_cpp_BIN}")
+
+ set(rosidl_typesupport_protobuf_cpp_GENERATOR_FILES
+ "${rosidl_typesupport_protobuf_cpp_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_typesupport_protobuf_cpp/__init__.py")
+ normalize_path(rosidl_typesupport_protobuf_cpp_GENERATOR_FILES
+ "${rosidl_typesupport_protobuf_cpp_GENERATOR_FILES}")
+
+ set(rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR
+ "${rosidl_typesupport_protobuf_cpp_DIR}/../resource")
+ normalize_path(rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}")
+endif()
diff --git a/rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp_generate_interfaces.cmake b/rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp_generate_interfaces.cmake
new file mode 100644
index 0000000..62c4068
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp_generate_interfaces.cmake
@@ -0,0 +1,203 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+find_package(Protobuf REQUIRED)
+
+find_package(rosidl_adapter_proto REQUIRED)
+find_package(rosidl_typesupport_protobuf REQUIRED)
+
+set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_cpp/${PROJECT_NAME}")
+
+# Create a list of files that will be generated from each IDL file
+set(_generated_files "")
+foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES})
+ get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY)
+ get_filename_component(_parent_folder "${_parent_folder}" NAME)
+ get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE)
+ # Turn idl name into file names
+ string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name)
+ list(APPEND _generated_files
+ "${_output_path}/${_parent_folder}/detail/${_header_name}__type_support.cpp"
+ "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_protobuf_cpp.hpp"
+ )
+endforeach()
+
+# Create a list of IDL files from other packages that this generator should depend on
+set(_dependency_files "")
+set(_dependencies "")
+foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
+ foreach(_idl_file ${${_pkg_name}_IDL_FILES})
+ # ${{_pkg_name}_DIR} is absolute path ending in 'share//cmake', so go back one
+ # directory for IDL files
+ set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
+ normalize_path(_abs_idl_file "${_abs_idl_file}")
+ list(APPEND _dependency_files "${_abs_idl_file}")
+ list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
+ endforeach()
+endforeach()
+
+# Create a list of templates and source files this generator uses, and check that they exist
+set(target_dependencies
+ "${rosidl_typesupport_protobuf_cpp_BIN}"
+ ${rosidl_typesupport_protobuf_cpp_GENERATOR_FILES}
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/idl__rosidl_typesupport_protobuf_cpp.hpp.em"
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/idl__type_support.cpp.em"
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/msg__rosidl_typesupport_protobuf_cpp.hpp.em"
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/msg__type_support.cpp.em"
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/srv__rosidl_typesupport_protobuf_cpp.hpp.em"
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/srv__type_support.cpp.em"
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/rosidl_typesupport_protobuf_cpp__visibility_control.h.in"
+ ${rosidl_generate_interfaces_ABS_IDL_FILES}
+ ${_dependency_files}
+)
+foreach(dep ${target_dependencies})
+ if(NOT EXISTS "${dep}")
+ message(FATAL_ERROR "Target dependency '${dep}' does not exist")
+ endif()
+endforeach()
+
+# Write all this to a file to work around command line length limitations on some platforms
+set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_cpp__arguments.json")
+rosidl_write_generator_arguments(
+ "${generator_arguments_file}"
+ PACKAGE_NAME "${PROJECT_NAME}"
+ IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}"
+ ROS_INTERFACE_DEPENDENCIES "${_dependencies}"
+ OUTPUT_DIR "${_output_path}"
+ TEMPLATE_DIR "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}"
+ TARGET_DEPENDENCIES ${target_dependencies}
+)
+
+# Add a command that invokes generator at build time
+add_custom_command(
+ OUTPUT ${_generated_files}
+ COMMAND ${PYTHON_EXECUTABLE} ${rosidl_typesupport_protobuf_cpp_BIN}
+ --generator-arguments-file "${generator_arguments_file}"
+ DEPENDS ${target_dependencies}
+ COMMENT "Generating C++ type support for Protobuf"
+ VERBATIM
+)
+
+# generate header to switch between export and import for a specific package
+set(_visibility_control_file
+"${_output_path}/rosidl_typesupport_protobuf_cpp__visibility_control.h")
+string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER)
+configure_file(
+ "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}/rosidl_typesupport_protobuf_cpp__visibility_control.h.in"
+ "${_visibility_control_file}"
+ @ONLY
+)
+
+set(_target_suffix "__rosidl_typesupport_protobuf_cpp")
+
+add_library(${rosidl_generate_interfaces_TARGET}${_target_suffix} SHARED
+ ${_generated_files}
+ ${rosidl_adapter_proto_GENERATED_CPP}
+)
+
+# Change output library name if asked to
+if(rosidl_generate_interfaces_LIBRARY_NAME)
+ set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PROPERTIES OUTPUT_NAME "${rosidl_generate_interfaces_LIBRARY_NAME}${_target_suffix}")
+endif()
+
+# set C++ standard
+set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PROPERTIES CXX_STANDARD 14
+)
+
+# Set flag for visibility macro
+if(WIN32)
+ target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PRIVATE "ROSIDL_TYPESUPPORT_PROTOBUF_BUILDING_DLL" "ROSIDL_TYPESUPPORT_PROTOBUF_CPP_BUILDING_DLL__${PROJECT_NAME}")
+ set (Protobuf_USE_STATIC_LIBS TRUE)
+endif()
+
+# Set compiler flags
+if(NOT WIN32)
+ set(_target_compile_flags "-Wall -Wextra -Wpedantic")
+else()
+ set(_target_compile_flags "/W4")
+endif()
+string(REPLACE ";" " " _target_compile_flags "${_target_compile_flags}")
+set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PROPERTIES COMPILE_FLAGS "${_target_compile_flags}"
+)
+
+# Include headers from other generators
+target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ PUBLIC
+ ${_output_path}
+ ${Protobuf_INCLUDE_DIR}
+ ${rosidl_adapter_proto_INCLUDE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_cpp
+)
+
+ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ rmw
+ rosidl_typesupport_protobuf
+ rosidl_typesupport_protobuf_cpp
+ rosidl_typesupport_interface
+)
+
+# Depend on dependencies
+foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
+ ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ${_pkg_name})
+ target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ${${_pkg_name}_LIBRARIES${_target_suffix}})
+endforeach()
+
+target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} ${Protobuf_LIBRARY})
+
+# Make top level generation target depend on this library
+add_dependencies(
+ ${rosidl_generate_interfaces_TARGET}
+ ${rosidl_generate_interfaces_TARGET}${_target_suffix}
+)
+
+# Make this library depend on target created by rosidl_generator_cpp
+add_dependencies(
+ ${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ${rosidl_generate_interfaces_TARGET}__cpp
+)
+
+if(NOT rosidl_generate_interfaces_SKIP_INSTALL)
+ install(
+ DIRECTORY "${_output_path}/"
+ DESTINATION "include/${PROJECT_NAME}"
+ PATTERN "*.cpp" EXCLUDE
+ )
+
+ if(NOT _generated_files STREQUAL "")
+ ament_export_include_directories(include)
+ endif()
+
+ install(
+ TARGETS ${rosidl_generate_interfaces_TARGET}${_target_suffix}
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin
+ )
+
+ rosidl_export_typesupport_libraries(${_target_suffix}
+ ${rosidl_generate_interfaces_TARGET}${_target_suffix})
+
+ ament_export_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix})
+endif()
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/identifier.hpp b/rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/identifier.hpp
new file mode 100644
index 0000000..083c23c
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/identifier.hpp
@@ -0,0 +1,30 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+namespace rosidl_typesupport_protobuf_cpp
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT
+extern const char *identifier;
+
+} // namespace rosidl_typesupport_protobuf_cpp
diff --git a/rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp b/rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp
new file mode 100644
index 0000000..e51b756
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp
@@ -0,0 +1,35 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#pragma once
+
+#include
+
+#include
+
+namespace rosidl_typesupport_protobuf_cpp
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+void write_to_string(const std::u16string &u16str, std::string &str);
+
+ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC
+void write_to_u16string(const std::string &str, std::u16string &u16str);
+
+}
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/package.xml b/rosidl_typesupport_protobuf_cpp/package.xml
new file mode 100644
index 0000000..5097a8f
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/package.xml
@@ -0,0 +1,34 @@
+
+
+
+ rosidl_typesupport_protobuf_cpp
+ 0.0.1
+ Generate the C++ interfaces for Protobuf serialization.
+ Aleksandar Brakmić
+ Apache License 2.0
+
+ ament_cmake
+ rosidl_cmake
+ rosidl_generator_cpp
+ rosidl_adapter_proto
+ rosidl_typesupport_protobuf
+
+ ament_cmake
+ rosidl_cmake
+ rosidl_generator_cpp
+ rosidl_adapter_proto
+ rosidl_typesupport_protobuf
+
+ rmw
+
+ rosidl_parser
+ rosidl_adapter_proto
+ rosidl_typesupport_interface
+ rosidl_typesupport_protobuf
+
+ rosidl_typesupport_cpp_packages
+
+
+ ament_cmake
+
+
diff --git a/rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em b/rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em
new file mode 100644
index 0000000..7dedcec
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em
@@ -0,0 +1,92 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+// generated from rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em
+// with input from @(package_name):@(interface_path)
+// generated code does not contain a copyright notice
+@
+@#######################################################################
+@# EmPy template for generating __rosidl_typesupport_protobuf_cpp.hpp files
+@#
+@# Context:
+@# - package_name (string)
+@# - interface_path (Path relative to the directory named after the package)
+@# - content (IdlContent, list of elements, e.g. Messages or Services)
+@#######################################################################
+@
+#pragma once
+
+@{
+
+include_directives = set()
+
+#######################################################################
+# Handle message
+#######################################################################
+from rosidl_parser.definition import Message
+for message in content.get_elements_of_type(Message):
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=message,
+ include_directives=include_directives)
+
+#######################################################################
+# Handle service
+#######################################################################
+from rosidl_parser.definition import Service
+for service in content.get_elements_of_type(Service):
+ TEMPLATE(
+ 'srv__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ service=service,
+ include_directives=include_directives)
+
+#######################################################################
+# Handle action
+#######################################################################
+from rosidl_parser.definition import Action
+for action in content.get_elements_of_type(Action):
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.goal,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.result,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'srv__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.send_goal_service,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'srv__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.get_result_service,
+ include_directives=include_directives)
+ TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback_message,
+ include_directives=include_directives)
+}@
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em b/rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em
new file mode 100644
index 0000000..f1f18d3
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em
@@ -0,0 +1,118 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+// generated from rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em
+// with input from @(package_name):@(interface_path)
+// generated code does not contain a copyright notice
+@
+@#######################################################################
+@# EmPy template for generating __type_support.cpp files
+@#
+@# Context:
+@# - package_name (string)
+@# - interface_path (Path relative to the directory named after the package)
+@# - content (IdlContent, list of elements, e.g. Messages or Services)
+@#######################################################################
+@
+@{
+from rosidl_typesupport_protobuf import typesupport_header, ros_message_header
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+
+include_directives = set()
+forward_declared_types = set()
+
+system_header_files = []
+header_files = [
+ typesupport_header(package_name, interface_path),
+ ros_message_header(package_name, interface_path)
+]
+}@
+
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+#######################################################################
+# Handle message
+#######################################################################
+from rosidl_parser.definition import Message
+for message in content.get_elements_of_type(Message):
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+
+#######################################################################
+# Handle service
+#######################################################################
+from rosidl_parser.definition import Service
+for service in content.get_elements_of_type(Service):
+ TEMPLATE(
+ 'srv__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ service=service,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+
+#######################################################################
+# Handle action
+#######################################################################
+from rosidl_parser.definition import Action
+for action in content.get_elements_of_type(Action):
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.goal,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.result,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'srv__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.send_goal_service,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'srv__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, service=action.get_result_service,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+ TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name, interface_path=interface_path, message=action.feedback_message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+}@
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/resource/msg__rosidl_typesupport_protobuf_cpp.hpp.em b/rosidl_typesupport_protobuf_cpp/resource/msg__rosidl_typesupport_protobuf_cpp.hpp.em
new file mode 100644
index 0000000..c707f80
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/msg__rosidl_typesupport_protobuf_cpp.hpp.em
@@ -0,0 +1,83 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@# Included from rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em
+@{
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_typesupport_protobuf import *
+
+system_header_files = [
+ "string"
+]
+
+header_files = [
+ ros_message_header(package_name, interface_path),
+ visibility_control_header(package_name),
+ 'rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp',
+ 'rosidl_typesupport_interface/macros.h',
+ protobuf_message_header(package_name, interface_path)
+]
+
+ros_type_ns = ros_type_namespace(package_name, interface_path)
+ros_type_name = ros_type_name(message)
+ros_type = ros_type(package_name, interface_path, message)
+proto_type = protobuf_type(package_name, interface_path, message)
+
+}@
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@[for ns in message.structure.namespaced_type.namespaces]@
+namespace @(ns)
+{
+@[end for]@
+namespace typesupport_protobuf_cpp
+{
+
+bool
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name)
+convert_to_proto(const @(ros_type) &ros_msg, @(proto_type) &pb_msg);
+
+bool
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name)
+convert_to_ros(const @(proto_type) &pb_msg, @(ros_type) &ros_msg);
+
+} // namespace typesupport_protobuf_cpp
+@[ for ns in reversed(message.structure.namespaced_type.namespaces)]@
+} // namespace @(ns)
+@[ end for]@
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name)
+const rosidl_message_type_support_t *
+ ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(ros_type_ns.replace("::", ", ")), @(ros_type_name))();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_cpp/resource/msg__type_support.cpp.em b/rosidl_typesupport_protobuf_cpp/resource/msg__type_support.cpp.em
new file mode 100644
index 0000000..a58c86a
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/msg__type_support.cpp.em
@@ -0,0 +1,239 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@# Included from rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em
+@{
+import rosidl_parser.parser as rosidl
+from rosidl_parser.definition import *
+from rosidl_typesupport_protobuf import *
+
+ros_type_ns = ros_type_namespace(package_name, interface_path)
+ros_type_name = ros_type_name(message)
+ros_type = ros_type(package_name=package_name, interface_path=interface_path, message=message)
+proto_type = protobuf_type(package_name=package_name, interface_path=interface_path, message=message)
+
+system_header_files = [
+ 'string',
+ 'algorithm'
+]
+
+header_files = [
+ 'rosidl_typesupport_cpp/message_type_support.hpp',
+ 'rosidl_typesupport_protobuf_cpp/identifier.hpp',
+ 'rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp',
+ 'rosidl_typesupport_protobuf/message_type_support.hpp',
+ 'rosidl_typesupport_protobuf/message_type_support_decl.hpp',
+ 'rosidl_typesupport_protobuf/proto_descriptor_helper.hpp',
+ visibility_control_header(package_name),
+ protobuf_message_header(package_name, interface_path)
+]
+}@
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+TEMPLATE(
+ 'tmpl_forward_declarations.em',
+ message=message,
+ forward_declared_types=forward_declared_types
+)
+}@
+@[ for ns in message.structure.namespaced_type.namespaces]@
+namespace @(ns)
+{
+@[ end for]@
+namespace typesupport_protobuf_cpp
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name)
+bool convert_to_proto(const @(ros_type) &ros_msg, @(proto_type) &pb_msg)
+{
+@[for member in message.structure.members]@
+ // Member: @(member.name)
+@[ if isinstance(member.type, AbstractNestedType)]@
+@[ if isinstance(member.type.value_type, BasicType) or isinstance(member.type.value_type, AbstractString)]@
+ *pb_msg.mutable_@(member.name)() = { ros_msg.@(member.name).begin(), ros_msg.@(member.name).end() };
+@[ elif isinstance(member.type.value_type, AbstractWString)]@
+ for(auto &member : ros_msg.@(member.name))
+ {
+ ::rosidl_typesupport_protobuf_cpp::write_to_string(member, *pb_msg.add_@(member.name)());
+ }
+@[ elif isinstance(member.type.value_type, NamespacedType)]@
+ for(auto &member : ros_msg.@(member.name))
+ {
+ auto ptr{pb_msg.add_@(member.name)()};
+ @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_cpp::convert_to_proto(member, *ptr);
+ }
+@[ end if]@
+@[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractString)]@
+ pb_msg.set_@(member.name)(ros_msg.@(member.name));
+@[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractWString)]@
+ ::rosidl_typesupport_protobuf_cpp::write_to_string(ros_msg.@(member.name), *pb_msg.mutable_@(member.name)());
+@[ elif isinstance(member.type, NamespacedType)]@
+ @("::" + "::".join(member.type.namespaces))::typesupport_protobuf_cpp::convert_to_proto(ros_msg.@(member.name), *pb_msg.mutable_@(member.name)());
+@[ end if]@
+@[end for]@
+
+ return true;
+}
+
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name)
+bool convert_to_ros(const @(proto_type) &pb_msg, @(ros_type) &ros_msg)
+{
+@[for member in message.structure.members]@
+ // Member: @(member.name)
+@[ if isinstance(member.type, AbstractNestedType)]@
+@[ if isinstance(member.type.value_type, BasicType) or isinstance(member.type.value_type, AbstractString)]@
+@[ if isinstance(member.type, Array)]@
+ std::copy_n(pb_msg.@(member.name)().begin(), ros_msg.@(member.name).size(), ros_msg.@(member.name).begin());
+@[ else]@
+@[ if isinstance(member.type.value_type, BasicType) and member.type.value_type.typename == BOOLEAN_TYPE]@
+ for(auto val : pb_msg.@(member.name)())
+ {
+ ros_msg.@(member.name).push_back(val);
+ }
+@[ else]@
+ ros_msg.@(member.name) = { pb_msg.@(member.name)().begin(), pb_msg.@(member.name)().end() };
+@[ end if]@
+@[ end if]@
+@[ elif isinstance(member.type.value_type, AbstractWString)]@
+ {
+@[ if not isinstance(member.type, Array)]@
+ auto size{pb_msg.@(member.name)_size()};
+ ros_msg.@(member.name).resize(size);
+
+@[ end if]@
+ auto& data{pb_msg.@(member.name)()};
+ auto& ros_data{ros_msg.@(member.name)};
+ int i{0};
+ for(auto &str : data)
+ {
+ ::rosidl_typesupport_protobuf_cpp::write_to_u16string(str, ros_data[i]);
+ i++;
+ }
+ }
+@[ elif isinstance(member.type.value_type, NamespacedType)]@
+ {
+@[ if not isinstance(member.type, Array)]@
+ auto size{pb_msg.@(member.name)_size()};
+ ros_msg.@(member.name).resize(size);
+
+@[ end if]@
+ auto& data{pb_msg.@(member.name)()};
+ auto& ros_data{ros_msg.@(member.name)};
+ int i{0};
+ for(auto &member : data)
+ {
+ //auto ptr = pb_msg.add_@(member.name)();
+ @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_cpp::convert_to_ros(member, ros_data[i]);
+ i++;
+ }
+ }
+@[ end if]@
+@[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractString)]@
+ ros_msg.@(member.name) = pb_msg.@(member.name)();
+@[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractWString)]@
+ ::rosidl_typesupport_protobuf_cpp::write_to_u16string(pb_msg.@(member.name)(), ros_msg.@(member.name));
+@[ elif isinstance(member.type, NamespacedType)]@
+ @("::" + "::".join(member.type.namespaces))::typesupport_protobuf_cpp::convert_to_ros(pb_msg.@(member.name)(), ros_msg.@(member.name));
+@[ end if]@
+@[end for]@
+
+ return true;
+}
+
+static bool _@(ros_type_name)__serialize(const void *untyped_ros_msg, std::string &serialized_msg)
+{
+ @(proto_type) pb_msg{};
+ auto ros_msg{static_cast(untyped_ros_msg)};
+
+ convert_to_proto(*ros_msg, pb_msg);
+ return pb_msg.SerializeToString(&serialized_msg);
+}
+
+static bool _@(ros_type_name)__deserialize(void *untyped_ros_msg, const void *serialized_msg, size_t size)
+{
+ @(proto_type) pb_msg{};
+ auto ros_msg{static_cast<@(ros_type) *>(untyped_ros_msg)};
+
+ pb_msg.ParseFromArray(serialized_msg, size);
+ return convert_to_ros(pb_msg, *ros_msg);
+}
+
+static std::string _@(ros_type_name)__get_descriptor()
+{
+ return "";
+ return GetProtoMessageDescription<@(proto_type)>();
+}
+
+@{type_support_name = "_" + ros_type_name + "__type_support"}@
+static rosidl_typesupport_protobuf::message_type_support_t @(type_support_name) = {
+ "@(ros_type_ns)",
+ "@(ros_type_name)",
+ _@(ros_type_name)__serialize,
+ _@(ros_type_name)__deserialize,
+ _@(ros_type_name)__get_descriptor
+};
+
+@{
+handle_name = "_" + ros_type_name + "__handle"
+namespaced_handle_name = "::".join([ros_type_ns, "typesupport_protobuf_cpp", handle_name])
+}@
+static rosidl_message_type_support_t @(handle_name) = {
+ rosidl_typesupport_protobuf_cpp::identifier,
+ &@(type_support_name),
+ get_message_typesupport_handle_function
+};
+
+} // namespace typesupport_protobuf_cpp
+@[ for ns in reversed(message.structure.namespaced_type.namespaces)]@
+} // namespace @(ns)
+@[ end for]@
+
+namespace rosidl_typesupport_protobuf
+{
+
+template<>
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@(package_name)
+const rosidl_message_type_support_t *get_message_type_support_handle<@(ros_type)>()
+{
+ return &@(namespaced_handle_name);
+}
+
+} // namespace rosidl_typesupport_protobuf
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(ros_type_ns.replace("::", ", ")), @(ros_type_name))() {
+ return &@(namespaced_handle_name);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_cpp/resource/rosidl_typesupport_protobuf_cpp__visibility_control.h.in b/rosidl_typesupport_protobuf_cpp/resource/rosidl_typesupport_protobuf_cpp__visibility_control.h.in
new file mode 100644
index 0000000..f9b08dd
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/rosidl_typesupport_protobuf_cpp__visibility_control.h.in
@@ -0,0 +1,42 @@
+// generated from
+// rosidl_typesupport_protobuf/rosidl_typesupport_protobuf_cpp/resource/visibility_control.h.in
+// generated code does not contain a copyright notice
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// This logic was borrowed (then namespaced) from the examples on the gcc wiki:
+// https://gcc.gnu.org/wiki/Visibility
+
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef __GNUC__
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@ __attribute__ ((dllexport))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@ __attribute__ ((dllimport))
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@ __declspec(dllexport)
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@ __declspec(dllimport)
+ #endif
+ #ifdef ROSIDL_TYPESUPPORT_PROTOBUF_CPP_BUILDING_DLL__@PROJECT_NAME@
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@
+ #endif
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_LOCAL__@PROJECT_NAME@
+#else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@ __attribute__ ((visibility("default")))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@
+ #if __GNUC__ >= 4
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@ __attribute__ ((visibility("default")))
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_LOCAL__@PROJECT_NAME@ __attribute__ ((visibility("hidden")))
+ #else
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@
+ #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_LOCAL__@PROJECT_NAME@
+ #endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/resource/srv__rosidl_typesupport_protobuf_cpp.hpp.em b/rosidl_typesupport_protobuf_cpp/resource/srv__rosidl_typesupport_protobuf_cpp.hpp.em
new file mode 100644
index 0000000..52b6a1f
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/srv__rosidl_typesupport_protobuf_cpp.hpp.em
@@ -0,0 +1,47 @@
+@# Included from rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em
+@{
+system_header_files = []
+header_files = [
+ 'rosidl_typesupport_cpp/service_type_support.hpp',
+ 'rosidl_typesupport_interface/macros.h'
+]
+}@
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files=system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.request_message,
+ include_directives=include_directives)
+}@
+
+@{
+TEMPLATE(
+ 'msg__rosidl_typesupport_protobuf_cpp.hpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.response_message,
+ include_directives=include_directives)
+}@
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name)
+const rosidl_service_type_support_t *
+ ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name])))();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_cpp/resource/srv__type_support.cpp.em b/rosidl_typesupport_protobuf_cpp/resource/srv__type_support.cpp.em
new file mode 100644
index 0000000..e555c0b
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/srv__type_support.cpp.em
@@ -0,0 +1,115 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@# Included from rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em
+@{
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_typesupport_protobuf import ros_service_name, ros_service_namespace, ros_service_type
+
+system_header_files = []
+header_files = [
+ 'rosidl_typesupport_protobuf_cpp/identifier.hpp',
+ 'rosidl_typesupport_protobuf/service_type_support.hpp',
+ 'rosidl_typesupport_protobuf/service_type_support_decl.hpp'
+]
+
+service_name = ros_service_name(service)
+service_namespace = ros_service_namespace(package_name, interface_path)
+service_type = ros_service_type(package_name, interface_path, service)
+
+}@
+@{
+TEMPLATE(
+ 'tmpl_include_directories.em',
+ header_files=header_files,
+ system_header_files = system_header_files,
+ include_directives=include_directives
+)
+}@
+
+@{
+TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.request_message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+}@
+@{
+TEMPLATE(
+ 'msg__type_support.cpp.em',
+ package_name=package_name,
+ interface_path=interface_path,
+ message=service.response_message,
+ include_directives=include_directives,
+ forward_declared_types = forward_declared_types)
+}@
+
+@[for ns in service.namespaced_type.namespaces]@
+namespace @(ns)
+{
+@[end for]@
+namespace typesupport_protobuf_cpp
+{
+
+static rosidl_typesupport_protobuf::service_type_support_t _@(service_name)__callbacks = {
+ "@(service_namespace)",
+ "@(service_name)",
+ ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Request)(),
+ ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Response)(),
+};
+
+static rosidl_service_type_support_t _@(service.namespaced_type.name)__handle = {
+ rosidl_typesupport_protobuf_cpp::identifier,
+ &_@(service_name)__callbacks,
+ get_service_typesupport_handle_function,
+};
+
+} // namespace typesupport_protobuf_cpp
+@[for ns in reversed(service.namespaced_type.namespaces)]@
+} // namespace @(ns)
+@[end for]@
+
+namespace rosidl_typesupport_protobuf
+{
+
+template<>
+ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@(package_name)
+const rosidl_service_type_support_t *
+get_service_type_support_handle<@(service_type)>()
+{
+ return &@(service_namespace)::typesupport_protobuf_cpp::_@(service_name)__handle;
+}
+
+} // namespace rosidl_typesupport_protobuf
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+const rosidl_service_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))() {
+ return &@(service_namespace)::typesupport_protobuf_cpp::_@(service_name)__handle;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rosidl_typesupport_protobuf_cpp/resource/tmpl_forward_declarations.em b/rosidl_typesupport_protobuf_cpp/resource/tmpl_forward_declarations.em
new file mode 100644
index 0000000..3fe7784
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/tmpl_forward_declarations.em
@@ -0,0 +1,73 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+from rosidl_parser.definition import *
+from rosidl_typesupport_protobuf import PROTO_PACKAGE_POSTFIX, ros_type_from_namespaced_type, protobuf_type_from_namespaced_type
+
+def isNamespacedType(type_):
+ from rosidl_parser.definition import NamespacedType
+ return isinstance(type_, NamespacedType)
+
+def isNamespacedArrayType(type_):
+ from rosidl_parser.definition import AbstractNestedType
+ from rosidl_parser.definition import NamespacedType
+ return isinstance(type_, AbstractNestedType) and isinstance(type_.value_type, NamespacedType)
+
+def isTypeAlreadyDeclared(type_, fw_declared_types):
+ from rosidl_typesupport_protobuf import ros_type_from_namespaced_type
+ return ros_type_from_namespaced_type(type_) in fw_declared_types
+
+def registerDeclaredType(type_, fw_declared_types):
+ from rosidl_typesupport_protobuf import ros_type_from_namespaced_type
+ fw_declared_types.add(ros_type_from_namespaced_type(type_))
+
+types_to_declare = list()
+for member in message.structure.members:
+ if isNamespacedType(member.type) and not isTypeAlreadyDeclared(member.type, forward_declared_types):
+ types_to_declare.append(member.type)
+ registerDeclaredType(member.type, forward_declared_types)
+ elif isNamespacedArrayType(member.type) and not isTypeAlreadyDeclared(member.type.value_type, forward_declared_types):
+ types_to_declare.append(member.type.value_type)
+ registerDeclaredType(member.type.value_type, forward_declared_types)
+}@
+@[if len(types_to_declare) > 0]@
+// forward declaration of message dependencies and their conversion functions
+@[end if]@
+@[for type_ in types_to_declare]@
+@{
+ros_type = ros_type_from_namespaced_type(type_)
+proto_type = protobuf_type_from_namespaced_type(type_)
+}@
+@[ for ns in type_.namespaces]@
+namespace @(ns)
+{
+@[ end for]@
+namespace typesupport_protobuf_cpp
+{
+
+bool convert_to_proto(const @(ros_type)&, @(proto_type)&);
+bool convert_to_ros(const @(proto_type)&, @(ros_type)&);
+
+} // namespace typesupport_protobuf_cpp
+@[ for ns in reversed(type_.namespaces)]@
+} // namespace @(ns)
+@[ end for]@
+
+@[end for]@
diff --git a/rosidl_typesupport_protobuf_cpp/resource/tmpl_include_directories.em b/rosidl_typesupport_protobuf_cpp/resource/tmpl_include_directories.em
new file mode 100644
index 0000000..fe7a311
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/resource/tmpl_include_directories.em
@@ -0,0 +1,47 @@
+@{
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+}@
+@{
+def is_protobuf_header(header_file):
+ header_file.endswith(".pb.h")
+}
+@[for header_file in system_header_files]@
+@[ if header_file not in include_directives]@
+@{include_directives.add(header_file)}@
+#include <@(header_file)>
+@[ end if]@
+@[end for]@
+
+@[for header_file in header_files]@
+@[ if header_file not in include_directives]@
+@{include_directives.add(header_file)}@
+@[ if is_protobuf_header(header_file)]@
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4127 4146 4800)
+#endif
+#include "@(header_file)"
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+@[ else]@
+#include "@(header_file)"
+@[ end if]@
+@[ end if]@
+@[end for]@
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py
new file mode 100644
index 0000000..644abe8
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py
@@ -0,0 +1,29 @@
+# ================================= Apache 2.0 =================================
+#
+# Copyright (C) 2021 Continental
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ================================= Apache 2.0 =================================
+
+import rosidl_typesupport_protobuf
+
+from rosidl_cmake import generate_files, convert_camel_case_to_lower_case_underscore
+
+def generate_cpp(generator_arguments_file):
+ mapping = {
+ "idl__rosidl_typesupport_protobuf_cpp.hpp.em": "%s__rosidl_typesupport_protobuf_cpp.hpp",
+ "idl__type_support.cpp.em": "detail/%s__type_support.cpp",
+ }
+ generate_files(generator_arguments_file, mapping)
+ return 0
\ No newline at end of file
diff --git a/rosidl_typesupport_protobuf_cpp/src/identifier.cpp b/rosidl_typesupport_protobuf_cpp/src/identifier.cpp
new file mode 100644
index 0000000..29754be
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/src/identifier.cpp
@@ -0,0 +1,28 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#include
+
+namespace rosidl_typesupport_protobuf_cpp
+{
+
+ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT
+const char *identifier = "rosidl_typesupport_protobuf_cpp";
+
+} // namespace rosidl_typesupport_protobuf_cpp
diff --git a/rosidl_typesupport_protobuf_cpp/src/wstring_conversion.cpp b/rosidl_typesupport_protobuf_cpp/src/wstring_conversion.cpp
new file mode 100644
index 0000000..0dc9eb6
--- /dev/null
+++ b/rosidl_typesupport_protobuf_cpp/src/wstring_conversion.cpp
@@ -0,0 +1,42 @@
+/* ================================ Apache 2.0 =================================
+ *
+ * Copyright (C) 2021 Continental
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ================================ Apache 2.0 =================================
+ */
+
+#include "rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp"
+
+#include
+
+namespace rosidl_typesupport_protobuf_cpp
+{
+
+void write_to_string(const std::u16string &u16str, std::string &str)
+{
+ auto data_size = u16str.size() * sizeof(std::u16string::value_type);
+ str.resize(data_size);
+ auto str_start = &str[0];
+ std::memcpy(str_start, u16str.data(), data_size);
+}
+
+void write_to_u16string(const std::string &str, std::u16string &u16str)
+{
+ u16str.resize(str.size() / sizeof(std::u16string::value_type));
+ auto wstr_start = &u16str[0];
+ std::memcpy(wstr_start, str.data(), str.size());
+}
+
+}
\ No newline at end of file