openPMD-api
 
Loading...
Searching...
No Matches
JSON_internal.hpp
1/* Copyright 2020-2025 Franz Poeschel, Axel Huebl
2 *
3 * This file is part of openPMD-api.
4 *
5 * openPMD-api is free software: you can redistribute it and/or modify
6 * it under the terms of of either the GNU General Public License or
7 * the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * openPMD-api is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License and the GNU Lesser General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * and the GNU Lesser General Public License along with openPMD-api.
19 * If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#pragma once
23
24#include "openPMD/config.hpp"
25
26#include <deque>
27#include <nlohmann/json.hpp>
28#include <toml.hpp>
29
30#include <optional>
31
32#if openPMD_HAVE_MPI
33#include <mpi.h>
34#endif
35
36#include <memory> // std::shared_ptr
37#include <utility> // std::forward
38
39namespace openPMD
40{
41namespace json
42{
43 enum class SupportedLanguages
44 {
45 JSON,
46 TOML
47 };
48
50 {
51 nlohmann::json config = nlohmann::json::object();
52 SupportedLanguages originallySpecifiedAs{SupportedLanguages::JSON};
53 };
54
68 class TracingJSON
69 {
70 public:
71 TracingJSON();
72 TracingJSON(nlohmann::json, SupportedLanguages);
73 TracingJSON(ParsedConfig);
74
80 nlohmann::json &json();
81
91 nlohmann::json &json(std::vector<std::string> path);
92
93 template <typename Key>
94 TracingJSON operator[](Key &&key);
95
102 nlohmann::json const &getShadow() const;
103 nlohmann::json &getShadow();
104
111 nlohmann::json invertShadow() const;
112
120 void declareFullyRead();
121
122 SupportedLanguages originallySpecifiedAs{SupportedLanguages::JSON};
123
124 private:
131 std::shared_ptr<nlohmann::json> m_originalJSON;
141 std::shared_ptr<nlohmann::json> m_shadow;
147 nlohmann::json *m_positionInOriginal;
153 nlohmann::json *m_positionInShadow;
158 std::deque<std::string> m_positionForErrorMessages;
159 bool m_trace = true;
160
161 void invertShadow(
162 nlohmann::json &result, nlohmann::json const &shadow) const;
163
164 TracingJSON(
165 std::shared_ptr<nlohmann::json> originalJSON,
166 std::shared_ptr<nlohmann::json> shadow,
167 nlohmann::json *positionInOriginal,
168 nlohmann::json *positionInShadow,
169 std::deque<std::string> positionForErrorMessages,
170 SupportedLanguages originallySpecifiedAs,
171 bool trace);
172
173 void init();
174 /*
175 * Called upon each traced access of a location in the JSON value, along
176 * with the matching subtree of the shadow.
177 * This implements the `dont_warn_unused_keys` functionality.
178 */
179 static void init(
180 nlohmann::json const &original,
181 nlohmann::json &shadow,
182 std::deque<std::string> &positionForErrorMessages);
183 };
184
185 template <typename Key>
186 TracingJSON TracingJSON::operator[](Key &&key)
187 {
188 nlohmann::json *newPositionInOriginal =
189 &m_positionInOriginal->operator[](key);
190 // If accessing a leaf in the JSON tree from an object (not an array!)
191 // erase the corresponding key
192 static nlohmann::json nullvalue;
193 nlohmann::json *newPositionInShadow = &nullvalue;
194 if (m_trace && m_positionInOriginal->is_object())
195 {
196 newPositionInShadow = &m_positionInShadow->operator[](key);
197 }
198 bool traceFurther = newPositionInOriginal->is_object();
199 auto new_path = m_positionForErrorMessages;
200 new_path.push_back(std::forward<Key>(key));
201 return TracingJSON(
202 m_originalJSON,
203 m_shadow,
204 newPositionInOriginal,
205 newPositionInShadow,
206 std::move(new_path),
207 originallySpecifiedAs,
208 traceFurther);
209 }
210
211 nlohmann::json tomlToJson(toml::value const &val);
212 toml::value jsonToToml(nlohmann::json const &val);
213
226 ParsedConfig parseOptions(
227 std::string const &options,
228 bool considerFiles,
229 bool convertLowercase = true);
230
231#if openPMD_HAVE_MPI
232
236 ParsedConfig parseOptions(
237 std::string const &options,
238 MPI_Comm comm,
239 bool considerFiles,
240 bool convertLowercase = true);
241
242#endif
243
253 nlohmann::json &lowerCase(nlohmann::json &);
254
262 std::optional<std::string> asStringDynamic(nlohmann::json const &);
263
267 std::optional<std::string> asLowerCaseStringDynamic(nlohmann::json const &);
268
273 constexpr std::array<char const *, 4> backendKeys{
274 "adios2", "json", "toml", "hdf5"};
275
282 void warnGlobalUnusedOptions(TracingJSON const &config);
283
288 nlohmann::json &merge_internal(
289 nlohmann::json &defaultVal,
290 nlohmann::json const &overwrite,
291 bool do_prune);
292
293 nlohmann::json &filterByTemplate(
294 nlohmann::json &defaultVal, nlohmann::json const &positiveMask);
295
296 template <typename toml_t>
297 std::string format_toml(toml_t &&);
298} // namespace json
299} // namespace openPMD
Extend nlohmann::json with tracing of which keys have been accessed by operator[]().
Definition JSON_internal.hpp:69
void declareFullyRead()
Declare all keys of the current object read.
Definition JSON.cpp:141
nlohmann::json invertShadow() const
Invert the "shadow", i.e.
Definition JSON.cpp:98
nlohmann::json const & getShadow() const
Get the "shadow", i.e.
Definition JSON.cpp:88
nlohmann::json & json()
Access the underlying JSON value.
Definition JSON.cpp:65
Public definitions of openPMD-api.
Definition Date.cpp:29
Definition JSON_internal.hpp:50