P4C
The P4 Compiler
Loading...
Searching...
No Matches
json_generator.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef IR_JSON_GENERATOR_H_
18#define IR_JSON_GENERATOR_H_
19
20#include <optional>
21#include <string>
22#include <unordered_set>
23
24#include "ir/node.h"
25#include "lib/bitvec.h"
26#include "lib/cstring.h"
27#include "lib/indent.h"
28#include "lib/ltbitmatrix.h"
29#include "lib/match.h"
30#include "lib/ordered_map.h"
31#include "lib/ordered_set.h"
32#include "lib/safe_vector.h"
33
34namespace P4 {
35
37 std::unordered_set<int> node_refs;
38 std::ostream &out;
39 bool dumpSourceInfo;
40
41 template <typename T>
42 class has_toJSON {
43 typedef char small;
44 typedef struct {
45 char c[2];
46 } big;
47
48 template <typename C>
49 static small test(decltype(&C::toJSON));
50 template <typename C>
51 static big test(...);
52
53 public:
54 static const bool value = sizeof(test<T>(0)) == sizeof(char);
55 };
56
57 public:
58 indent_t indent;
59
60 explicit JSONGenerator(std::ostream &out, bool dumpSourceInfo = false)
61 : out(out), dumpSourceInfo(dumpSourceInfo) {}
62
63 template <typename T>
64 void generate(const safe_vector<T> &v) {
65 out << "[";
66 if (v.size() > 0) {
67 out << std::endl << ++indent;
68 generate(v[0]);
69 for (size_t i = 1; i < v.size(); i++) {
70 out << "," << std::endl << indent;
71 generate(v[i]);
72 }
73 out << std::endl << --indent;
74 }
75 out << "]";
76 }
77
78 template <typename T>
79 void generate(const std::vector<T> &v) {
80 out << "[";
81 if (v.size() > 0) {
82 out << std::endl << ++indent;
83 generate(v[0]);
84 for (size_t i = 1; i < v.size(); i++) {
85 out << "," << std::endl << indent;
86 generate(v[i]);
87 }
88 out << std::endl << --indent;
89 }
90 out << "]";
91 }
92
93 template <typename T, typename U>
94 void generate(const std::pair<T, U> &v) {
95 ++indent;
96 out << "{" << std::endl;
97 toJSON(v);
98 out << std::endl << --indent << "}";
99 }
100
101 template <typename T, typename U>
102 void toJSON(const std::pair<T, U> &v) {
103 out << indent << "\"first\" : ";
104 generate(v.first);
105 out << "," << std::endl << indent << "\"second\" : ";
106 generate(v.second);
107 }
108
109 template <typename T>
110 void generate(const std::optional<T> &v) {
111 if (!v) {
112 out << "{ \"valid\" : false }";
113 return;
114 }
115 out << "{" << std::endl << ++indent;
116 out << "\"valid\" : true," << std::endl;
117 out << "\"value\" : ";
118 generate(*v);
119 out << std::endl << --indent << "}";
120 }
121
122 template <typename T>
123 void generate(const std::set<T> &v) {
124 out << "[" << std::endl;
125 if (v.size() > 0) {
126 auto it = v.begin();
127 out << ++indent;
128 generate(*it);
129 for (it++; it != v.end(); ++it) {
130 out << "," << std::endl << indent;
131 generate(*it);
132 }
133 out << std::endl << --indent;
134 }
135 out << "]";
136 }
137
138 template <typename T>
139 void generate(const ordered_set<T> &v) {
140 out << "[" << std::endl;
141 if (v.size() > 0) {
142 auto it = v.begin();
143 out << ++indent;
144 generate(*it);
145 for (it++; it != v.end(); ++it) {
146 out << "," << std::endl << indent;
147 generate(*it);
148 }
149 out << std::endl << --indent;
150 }
151 out << "]";
152 }
153
154 template <typename K, typename V>
155 void generate(const std::map<K, V> &v) {
156 out << "[" << std::endl;
157 if (v.size() > 0) {
158 auto it = v.begin();
159 out << ++indent;
160 generate(*it);
161 for (it++; it != v.end(); ++it) {
162 out << "," << std::endl << indent;
163 generate(*it);
164 }
165 out << std::endl << --indent;
166 }
167 out << "]";
168 }
169
170 template <typename K, typename V>
171 void generate(const ordered_map<K, V> &v) {
172 out << "[" << std::endl;
173 if (v.size() > 0) {
174 auto it = v.begin();
175 out << ++indent;
176 generate(*it);
177 for (it++; it != v.end(); ++it) {
178 out << "," << std::endl << indent;
179 generate(*it);
180 }
181 out << std::endl << --indent;
182 }
183 out << "]";
184 }
185
186 void generate(bool v) { out << (v ? "true" : "false"); }
187 template <typename T>
188 typename std::enable_if<std::is_integral<T>::value>::type generate(T v) {
189 out << std::to_string(v);
190 }
191 void generate(double v) { out << std::to_string(v); }
192 template <typename T>
193 typename std::enable_if<std::is_same<T, big_int>::value>::type generate(const T &v) {
194 out << v;
195 }
196
197 void generate(cstring v) {
198 if (v) {
199 out << "\"" << v.escapeJson() << "\"";
200 } else {
201 out << "null";
202 }
203 }
204 template <typename T>
205 typename std::enable_if<std::is_same<T, LTBitMatrix>::value || std::is_enum<T>::value>::type
206 generate(T v) {
207 out << "\"" << v << "\"";
208 }
209
210 void generate(const bitvec &v) { out << "\"" << v << "\""; }
211
212 void generate(const match_t &v) {
213 out << "{" << std::endl
214 << (indent + 1) << "\"word0\" : " << v.word0 << "," << std::endl
215 << (indent + 1) << "\"word1\" : " << v.word1 << std::endl
216 << indent << "}";
217 }
218
219 template <typename T>
220 typename std::enable_if<has_toJSON<T>::value && !std::is_base_of<IR::Node, T>::value>::type
221 generate(const T &v) {
222 ++indent;
223 out << "{" << std::endl;
224 v.toJSON(*this);
225 out << std::endl << --indent << "}";
226 }
227
228 void generate(const IR::Node &v) {
229 out << "{" << std::endl;
230 ++indent;
231 if (node_refs.find(v.id) != node_refs.end()) {
232 out << indent << "\"Node_ID\" : " << v.id;
233 } else {
234 node_refs.insert(v.id);
235 v.toJSON(*this);
236 if (dumpSourceInfo) {
237 v.sourceInfoToJSON(*this);
238 }
239 }
240 out << std::endl << --indent << "}";
241 }
242
243 template <typename T>
244 typename std::enable_if<std::is_pointer<T>::value &&
245 has_toJSON<typename std::remove_pointer<T>::type>::value>::type
246 generate(T v) {
247 if (v)
248 generate(*v);
249 else
250 out << "null";
251 }
252
253 template <typename T, size_t N>
254 void generate(const T (&v)[N]) {
255 out << "[";
256 if (N > 0) {
257 out << std::endl << ++indent;
258 generate(v[0]);
259 for (size_t i = 1; i < N; i++) {
260 out << "," << std::endl << indent;
261 generate(v[i]);
262 }
263 out << std::endl << --indent;
264 }
265 out << "]";
266 }
267
268 JSONGenerator &operator<<(char ch) {
269 out << ch;
270 return *this;
271 }
272 JSONGenerator &operator<<(const char *s) {
273 out << s;
274 return *this;
275 }
276 JSONGenerator &operator<<(indent_t i) {
277 out << i;
278 return *this;
279 }
280 JSONGenerator &operator<<(std::ostream &(*fn)(std::ostream &)) {
281 out << fn;
282 return *this;
283 }
284 template <typename T>
285 JSONGenerator &operator<<(const T &v) {
286 generate(v);
287 return *this;
288 }
289};
290
291} // namespace P4
292
293#endif /* IR_JSON_GENERATOR_H_ */
Definition node.h:94
Definition json_generator.h:36
Definition bitvec.h:120
Definition cstring.h:85
cstring escapeJson() const
Definition cstring.cpp:272
Definition indent.h:26
Definition ordered_map.h:32
Definition ordered_set.h:32
Definition safe_vector.h:27
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition match.h:36