NEURON
json_printer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
9 #include "utils/logger.hpp"
10 
11 #include <nlohmann/json.hpp>
12 
13 namespace nmodl {
14 namespace printer {
15 
16 /// Dump output to provided file
17 JSONPrinter::JSONPrinter(const std::string& filename) {
18  if (filename.empty()) {
19  throw std::runtime_error("Empty filename for JSONPrinter");
20  }
21 
22  ofs.open(filename.c_str());
23 
24  if (ofs.fail()) {
25  auto msg = "Error while opening file '" + filename + "' for JSONPrinter";
26  throw std::runtime_error(msg);
27  }
28 
29  sbuf = ofs.rdbuf();
30  result = std::make_shared<std::ostream>(sbuf);
31 }
32 
33 /// Add node to json (typically basic type)
34 void JSONPrinter::add_node(std::string value, const std::string& key) {
35  if (!block) {
36  throw std::logic_error{"Block not initialized (push_block missing?)"};
37  }
38 
39  json j;
40  j[key] = std::move(value);
41  block->front().push_back(std::move(j));
42 }
43 
44 /// Add property to the block which is added last
45 void JSONPrinter::add_block_property(std::string const& name, const std::string& value) {
46  if (block == nullptr) {
47  logger->warn("JSONPrinter : can't add property without block");
48  return;
49  }
50  (*block)[name] = value;
51 }
52 
53 /// Add new json object (typically start of new block)
54 /// name here is type of new block encountered
55 void JSONPrinter::push_block(const std::string& value, const std::string& key) {
56  if (block) {
57  stack.push(block);
58  }
59 
60  json j;
61  if (expand) {
62  j[key] = value;
63  j[child_key] = json::array();
64  } else {
65  j[value] = json::array();
66  }
67  block = std::shared_ptr<json>(new json(j));
68 }
69 
70 /// We finished processing a block, add processed block to it's parent block
72  if (!stack.empty()) {
73  auto current = block;
74  block = stack.top();
75  block->front().push_back(*current);
76  stack.pop();
77  }
78 }
79 
80 /// Dump json object to stream (typically at the end)
81 /// nspaces is number of spaces used for indentation
83  if (block) {
84  if (compact) {
85  *result << block->dump();
86  } else {
87  *result << block->dump(2);
88  }
89  ofs.close();
90  block = nullptr;
91  }
92 }
93 
94 } // namespace printer
95 } // namespace nmodl
void flush()
Dump json object to stream (typically at the end) nspaces is number of spaces used for indentation.
const std::string child_key
json key for children
bool expand
true if we need to expand keys i.e.
void add_node(std::string value, const std::string &key="name")
Add node to json (typically basic type)
void add_block_property(std::string const &name, const std::string &value)
Add property to the block which is added last.
std::shared_ptr< json > block
single (current) nmodl block / statement
std::shared_ptr< std::ostream > result
common output stream for file, cout or stringstream
void push_block(const std::string &value, const std::string &key="name")
Add new json object (typically start of new block) name here is type of new block encountered.
void pop_block()
We finished processing a block, add processed block to it's parent block.
JSONPrinter()
By default dump output to std::cout.
bool compact
true if need to print json in compact format
std::stack< std::shared_ptr< json > > stack
stack that holds all parent blocks / statements
#define key
Definition: tqueue.hpp:45
Helper class for printing AST in JSON form.
const char * name
Definition: init.cpp:16
void move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:200
nlohmann::json json
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
logger_type logger
Definition: logger.cpp:34
size_t j
static List * current
Definition: nrnunit.cpp:13
static uint32_t value
Definition: scoprand.cpp:25