From 7cc273ea8141088c3068c2e6952fc558ecac9e1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20Paris?= <rene.paris@in-tech.com>
Date: Wed, 12 Feb 2025 08:08:50 +0100
Subject: [PATCH] feat(JSON for modern C++): Integrate nlohmann_json library

Integrates the commonly used JSON library for convenient parsing
of custom properites, carring object data encoded as string.
---
 NOTICE.md                                     |  6 ++
 README.md                                     |  9 +--
 engine/BUILD.bazel                            |  2 +
 engine/CMakeLists.txt                         | 43 ++++++-------
 engine/third_party/deps.bzl                   |  2 +
 engine/third_party/nlohmann_json/BUILD.bazel  |  0
 .../nlohmann_json/nlohman_json.BUILD          |  6 ++
 .../nlohmann_json/nlohman_json.bzl            | 17 ++++++
 .../nlohmann_json/nlohmann_json.BUILD         |  6 ++
 .../nlohmann_json/nlohmann_json.bzl           | 17 ++++++
 utils/ci/conan/conanfile.txt                  |  1 +
 .../recipe/nlohmann_json/all/conandata.yml    | 21 +++++++
 .../recipe/nlohmann_json/all/conanfile.py     | 60 +++++++++++++++++++
 .../ci/conan/recipe/nlohmann_json/config.yml  | 20 +++++++
 utils/ci/scripts/20_configure.sh              |  1 +
 15 files changed, 186 insertions(+), 25 deletions(-)
 create mode 100644 engine/third_party/nlohmann_json/BUILD.bazel
 create mode 100644 engine/third_party/nlohmann_json/nlohman_json.BUILD
 create mode 100644 engine/third_party/nlohmann_json/nlohman_json.bzl
 create mode 100644 engine/third_party/nlohmann_json/nlohmann_json.BUILD
 create mode 100644 engine/third_party/nlohmann_json/nlohmann_json.bzl
 create mode 100644 utils/ci/conan/recipe/nlohmann_json/all/conandata.yml
 create mode 100644 utils/ci/conan/recipe/nlohmann_json/all/conanfile.py
 create mode 100644 utils/ci/conan/recipe/nlohmann_json/config.yml

diff --git a/NOTICE.md b/NOTICE.md
index 812ea2b8..c623d498 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -78,6 +78,12 @@ Yase
 units_nhh
  * License: MIT
 
+nlohmann (JSON for Modern C++)
+ * License: MIT License
+ * Homepage: https://nlohmann.github.io/json/
+ * Repository: https://github.com/nlohmann/json
+ * Version: 3.9.1
+
 MantleAPI
  * License: EPL 2.0
 
diff --git a/README.md b/README.md
index 0484affe..8877a85e 100644
--- a/README.md
+++ b/README.md
@@ -254,13 +254,14 @@ Converts `NET_ASAM_OPENSCENARIO::v1_3::ITransitionDynamics` object type to [mant
 
 | Dependency | Commit | Version | License |
 | ---------- | ------ | ------- | ------- |
+| [CPM](https://github.com/cpm-cmake/CPM.cmake) | 03705fc | 0.36.0 | MIT License |
+| [googletest](https://github.com/google/googletest) | f8d7d77 | 1.14.0 | BSD-3-Clause License |
+| [JSON for Modern C++](https://github.com/nlohmann/json) | db78ac1 | 3.9.1 | MIT License |
 | [MantleAPI](https://gitlab.eclipse.org/eclipse/openpass/mantle-api) | ce2a378d | 11.0.0 | EPL 2.0 |
+| [openpass/stochastics-library](https://gitlab.eclipse.org/eclipse/openpass/stochastics-library) | 6c9dde71 | 0.11.0 | EPL 2.0 |
 | [OpenSCENARIO API](https://github.com/RA-Consulting-GmbH/openscenario.api.test/) | 5980e88 | 1.4.0 | Apache 2.0 |
-| [YASE](https://gitlab.eclipse.org/eclipse/openpass/yase) | d0c0e58d | | EPL 2.0 |
 | [Units](https://github.com/nholthaus/units) | e27eed9 | 2.3.4 | MIT License |
-| [googletest](https://github.com/google/googletest) | f8d7d77 | 1.14.0 | BSD-3-Clause License |
-| [CPM](https://github.com/cpm-cmake/CPM.cmake) | 03705fc | 0.36.0 | MIT License |
-| [openpass/stochastics-library](https://gitlab.eclipse.org/eclipse/openpass/stochastics-library) | 6c9dde71 | 0.11.0 | EPL 2.0 |
+| [YASE](https://gitlab.eclipse.org/eclipse/openpass/yase) | d0c0e58d | | EPL 2.0 |
 
 # Issues
 
diff --git a/engine/BUILD.bazel b/engine/BUILD.bazel
index cbc396a1..eb4e99c3 100644
--- a/engine/BUILD.bazel
+++ b/engine/BUILD.bazel
@@ -29,6 +29,7 @@ cc_library(
     visibility = ["//visibility:public"],
     deps = [
         "@mantle_api",
+        "@nlohmann_json",
         "@open_scenario_parser",
         "@stochastics_library",
         "@units_nhh",
@@ -183,6 +184,7 @@ cc_test(
         ":open_scenario_engine_test_utils",
         "@googletest//:gtest_main",
         "@mantle_api//:test_utils",
+        "@nlohmann_json",
     ],
 )
 
diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt
index c6a104d6..05b6093a 100644
--- a/engine/CMakeLists.txt
+++ b/engine/CMakeLists.txt
@@ -23,11 +23,11 @@ if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE Release)
 endif()
 
-# YASE
-find_package(Yase REQUIRED)
-
-# units https://github.com/nholthaus/units (dependency of MantleAPI)
+find_package(MantleAPI REQUIRED)
+find_package(nlohmann_json REQUIRED)
+find_package(Stochastics REQUIRED)
 find_package(units REQUIRED)
+find_package(Yase REQUIRED)
 
 # googlemock
 include(CPM)
@@ -39,12 +39,6 @@ CPMAddPackage(
   OPTIONS "INSTALL_GTEST OFF" "gtest_force_shared_crt ON"
 )
 
-# MantleAPI https://gitlab.eclipse.org/eclipse/simopenpass/scenario_api
-find_package(MantleAPI REQUIRED)
-
-
-find_package(Stochastics REQUIRED)
-
 # see https://stackoverflow.com/a/58495612
 set(CMAKE_INSTALL_RPATH $ORIGIN)
 
@@ -70,12 +64,17 @@ target_include_directories(
             $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
 )
 
-target_link_libraries(${PROJECT_NAME} PUBLIC openscenario_api::shared 
-                                             antlr4_runtime::shared 
-                                             Yase::agnostic_behavior_tree 
-                                             units::units 
-                                             MantleAPI::MantleAPI
-                                      PRIVATE Stochastics::Stochastics)
+target_link_libraries(${PROJECT_NAME}
+  PUBLIC 
+    antlr4_runtime::shared 
+    MantleAPI::MantleAPI
+    units::units 
+    Yase::agnostic_behavior_tree 
+    openscenario_api::shared 
+  PRIVATE 
+    Stochastics::Stochastics
+    nlohmann_json::nlohmann_json
+)
 
 if(USE_CCACHE)
   find_program(CCACHE_FOUND ccache)
@@ -246,11 +245,13 @@ target_include_directories(
 
 target_link_libraries(
   ${PROJECT_NAME}Test
-  PRIVATE ${PROJECT_NAME}
-          Stochastics::Stochastics
-          antlr4_runtime::shared
-          GTest::gmock_main
-          pthread
+  PRIVATE
+    ${PROJECT_NAME}
+    antlr4_runtime::shared
+    GTest::gmock_main
+    nlohmann_json::nlohmann_json
+    pthread
+    Stochastics::Stochastics
 )
 
 add_test(NAME ${PROJECT_NAME}Test COMMAND ${PROJECT_NAME}Test)
diff --git a/engine/third_party/deps.bzl b/engine/third_party/deps.bzl
index 1f832f8a..8fdc2f6e 100644
--- a/engine/third_party/deps.bzl
+++ b/engine/third_party/deps.bzl
@@ -1,5 +1,6 @@
 load("@//third_party/boost:boost.bzl", "boost_deps")
 load("@//third_party/mantle_api:mantle_api.bzl", "mantle_api")
+load("@//third_party/nlohmann_json:nlohmann_json.bzl", "nlohmann_json")
 load("@//third_party/open_scenario_parser:open_scenario_parser.bzl", "open_scenario_parser")
 load("@//third_party/stochastics_library:stochastics_library.bzl", "stochastics_library")
 load("@//third_party/units:units.bzl", "units_nhh")
@@ -11,6 +12,7 @@ def osc_engine_deps():
     """Load dependencies"""
     boost_deps()
     mantle_api()
+    nlohmann_json()
     open_scenario_parser()
     stochastics_library()
     units_nhh()
diff --git a/engine/third_party/nlohmann_json/BUILD.bazel b/engine/third_party/nlohmann_json/BUILD.bazel
new file mode 100644
index 00000000..e69de29b
diff --git a/engine/third_party/nlohmann_json/nlohman_json.BUILD b/engine/third_party/nlohmann_json/nlohman_json.BUILD
new file mode 100644
index 00000000..d8fedf12
--- /dev/null
+++ b/engine/third_party/nlohmann_json/nlohman_json.BUILD
@@ -0,0 +1,6 @@
+cc_library(
+    name = "nlohmann_json",
+    hdrs = ["single_include/nlohmann/json.hpp"],
+    includes = ["single_include"],
+    visibility = ["//visibility:public"],
+)
diff --git a/engine/third_party/nlohmann_json/nlohman_json.bzl b/engine/third_party/nlohmann_json/nlohman_json.bzl
new file mode 100644
index 00000000..1df985c1
--- /dev/null
+++ b/engine/third_party/nlohmann_json/nlohman_json.bzl
@@ -0,0 +1,17 @@
+"""
+This module contains rule to pull nlohmann json
+"""
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:nlohmann_json.bzl", "maybe")
+
+_TAG = "3.9.1"
+
+def nlohmann_json():
+   maybe(
+        http_archive,
+        name = "nlohmann_json",
+        build_file = Label("//:third_party/nlohmann_json/nlohmann_json.BUILD"),
+        url =  "https://github.com/nlohmann/json/releases/download/v{version}/include.zip".format(version = _VERSION),
+        sha256 = "6bea5877b1541d353bd77bdfbdb2696333ae5ed8f9e8cc22df657192218cad91"
+    )
diff --git a/engine/third_party/nlohmann_json/nlohmann_json.BUILD b/engine/third_party/nlohmann_json/nlohmann_json.BUILD
new file mode 100644
index 00000000..d8fedf12
--- /dev/null
+++ b/engine/third_party/nlohmann_json/nlohmann_json.BUILD
@@ -0,0 +1,6 @@
+cc_library(
+    name = "nlohmann_json",
+    hdrs = ["single_include/nlohmann/json.hpp"],
+    includes = ["single_include"],
+    visibility = ["//visibility:public"],
+)
diff --git a/engine/third_party/nlohmann_json/nlohmann_json.bzl b/engine/third_party/nlohmann_json/nlohmann_json.bzl
new file mode 100644
index 00000000..ede618ec
--- /dev/null
+++ b/engine/third_party/nlohmann_json/nlohmann_json.bzl
@@ -0,0 +1,17 @@
+"""
+This module contains rule to pull nlohmann json
+"""
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
+
+_VERSION = "3.9.1"
+
+def nlohmann_json():
+    maybe(
+        http_archive,
+        name = "nlohmann_json",
+        build_file = Label("//:third_party/nlohmann_json/nlohmann_json.BUILD"),
+        url =  "https://github.com/nlohmann/json/releases/download/v{version}/include.zip".format(version = _VERSION),
+        sha256 = "6bea5877b1541d353bd77bdfbdb2696333ae5ed8f9e8cc22df657192218cad91"
+    )
diff --git a/utils/ci/conan/conanfile.txt b/utils/ci/conan/conanfile.txt
index 849dff88..ef49838b 100644
--- a/utils/ci/conan/conanfile.txt
+++ b/utils/ci/conan/conanfile.txt
@@ -1,6 +1,7 @@
 [requires]
 units/2.3.4@openscenarioengine/testing
 mantleapi/v11.0.0@openscenarioengine/testing
+nlohmann_json/v3.9.1@openscenarioengine/testing
 yase/d0c0e58d17358044cc9018c74308b45f6097ecfb@openscenarioengine/testing
 openscenario_api/v1.4.0@openscenarioengine/testing
 stochastics/0.11.0@openscenarioengine/testing
diff --git a/utils/ci/conan/recipe/nlohmann_json/all/conandata.yml b/utils/ci/conan/recipe/nlohmann_json/all/conandata.yml
new file mode 100644
index 00000000..3a9de20a
--- /dev/null
+++ b/utils/ci/conan/recipe/nlohmann_json/all/conandata.yml
@@ -0,0 +1,21 @@
+################################################################################
+# Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License 2.0 which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# SPDX-License-Identifier: EPL-2.0
+################################################################################
+
+################################################################################
+# conan data file for building nlohmann_json with Conan
+################################################################################
+
+sources:
+  "v3.9.1":
+    url: https://github.com/nlohmann/json/archive/refs/tags/v3.9.1.tar.gz
+    sha256: "4cf0df69731494668bdd6460ed8cb269b68de9c19ad8c27abc24cd72605b2d5b"
+  "v3.11.3":
+    url: https://github.com/nlohmann/json/archive/refs/tags/v3.11.3.tar.gz
+    sha256: "0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406"
diff --git a/utils/ci/conan/recipe/nlohmann_json/all/conanfile.py b/utils/ci/conan/recipe/nlohmann_json/all/conanfile.py
new file mode 100644
index 00000000..2a50d134
--- /dev/null
+++ b/utils/ci/conan/recipe/nlohmann_json/all/conanfile.py
@@ -0,0 +1,60 @@
+################################################################################
+# Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License 2.0 which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# SPDX-License-Identifier: EPL-2.0
+################################################################################
+
+################################################################################
+# Install file for building nlohmann_json with Conan
+################################################################################
+
+from conan import ConanFile
+from conan.tools.cmake import CMake, CMakeToolchain
+from conan.tools.files import rm, copy, rmdir
+from conan.tools.files import get, copy
+import os
+
+required_conan_version = ">=1.53"
+
+class NlohmannJSONConan(ConanFile):
+    name = "nlohmann_json"
+    settings = "os", "compiler", "build_type", "arch"
+    options = {"shared": [True, False],
+               "fPIC": [True, False]}
+
+    default_options = {"shared": False,
+                       "fPIC": True}
+
+    exports_sources = "*"
+    no_copy_source = False
+    short_paths = True
+
+    def config_options(self):
+        if self.settings.os == "Windows":
+            del self.options.fPIC
+
+    def configure(self):
+        if self.options.shared:
+            self.options.rm_safe("fPIC")
+
+    def generate(self):
+        tc = CMakeToolchain(self)
+        tc.generate()
+
+    def source(self):
+        get(self, **self.conan_data["sources"][self.version], strip_root=True)
+
+    def build(self):
+        cmake = CMake(self)
+        cmake.configure()
+
+    def package(self):
+        cmake = CMake(self)
+        cmake.install()
+
+    def package_info(self):
+        self.cpp_info.set_property("cmake_find_mode", "none")
diff --git a/utils/ci/conan/recipe/nlohmann_json/config.yml b/utils/ci/conan/recipe/nlohmann_json/config.yml
new file mode 100644
index 00000000..c2ea0f20
--- /dev/null
+++ b/utils/ci/conan/recipe/nlohmann_json/config.yml
@@ -0,0 +1,20 @@
+################################################################################
+# Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License 2.0 which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# SPDX-License-Identifier: EPL-2.0
+################################################################################
+
+################################################################################
+# config file for building nlohmann_json with Conan
+################################################################################
+
+versions:
+  "v3.9.1":
+    folder: "all"
+
+  "v3.11.3":
+    folder: "all"
diff --git a/utils/ci/scripts/20_configure.sh b/utils/ci/scripts/20_configure.sh
index 303502a8..8dc0b896 100755
--- a/utils/ci/scripts/20_configure.sh
+++ b/utils/ci/scripts/20_configure.sh
@@ -31,6 +31,7 @@ mkdir -p "$MYDIR/../../../../build"
 cd "$MYDIR/../../../../build" || exit 1
 
 DEPS=(
+  "$PWD/../deps/direct_deploy/nlohmann_json"
   "$PWD/../deps/direct_deploy/units"
   "$PWD/../deps/direct_deploy/mantleapi"
   "$PWD/../deps/direct_deploy/stochastics"
-- 
GitLab