Enforce Pos_or_decl.t in reasons for decl types
[hiphop-php.git] / hphp / compiler / json.h
blob931996e3d19a9583ea104b5b39ecb35b6a013093
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #pragma once
19 #include "hphp/util/hash-map.h"
21 #include <cassert>
22 #include <map>
23 #include <memory>
24 #include <ostream>
25 #include <set>
26 #include <vector>
28 namespace HPHP { namespace JSON {
29 ///////////////////////////////////////////////////////////////////////////////
31 template <typename T> struct _OutputStream;
32 template <typename T> struct _MapStream;
33 template <typename T> struct _ListStream;
34 template <typename T> struct _ISerializable;
36 #define DEFINE_JSON_OUTPUT_TYPE(type) \
37 struct type { \
38 typedef _OutputStream<type> OutputStream; \
39 typedef _MapStream<type> MapStream; \
40 typedef _ListStream<type> ListStream; \
41 typedef _ISerializable<type> ISerializable; \
44 DEFINE_JSON_OUTPUT_TYPE(CodeError);
46 std::string Escape(const char *s);
48 template <typename T>
49 struct _ISerializable {
50 virtual ~_ISerializable() {}
52 /**
53 * Generate JSON output of this data structure.
55 virtual void serialize(_OutputStream<T> &out) const = 0;
58 struct Name {
59 explicit Name(const char *name) {
60 assert(name && *name);
61 m_name = name;
63 explicit Name(const std::string &name) {
64 assert(!name.empty());
65 m_name = name;
67 const std::string &getName() const { return m_name; }
68 private:
69 std::string m_name;
72 // struct _Null {};
73 // _Null Null;
74 enum class Null {};
76 template <typename Type>
77 struct _OutputStream {
78 explicit _OutputStream(std::ostream &out) : m_out(out) {}
80 _OutputStream &operator<< (unsigned int v) { m_out << v; return *this; }
82 _OutputStream &operator<< (int v) { m_out << v; return *this; }
84 _OutputStream &operator<< (bool v) {
85 m_out << (v ? "true" : "false");
86 return *this;
89 _OutputStream &operator<< (const char *v) {
90 m_out << "\"" << Escape(v) << "\"";
91 return *this;
94 _OutputStream &operator<< (const std::string &v) {
95 m_out << "\"" << Escape(v.c_str()) << "\"";
96 return *this;
99 _OutputStream &operator<< (const Name &n) {
100 m_out << "\"" << n.getName() << "\":";
101 return *this;
104 _OutputStream& operator<<(const Null& /*n*/) {
105 m_out << "null";
106 return *this;
109 _OutputStream &operator<< (const _ISerializable<Type> &v) {
110 v.serialize(*this);
111 return *this;
114 template<typename T>
115 _OutputStream &operator<< (const std::shared_ptr<T> &v) {
116 if (v) {
117 *this << *v;
118 } else {
119 *this << Null();
121 return *this;
124 template<typename T>
125 _OutputStream &operator<< (const std::vector<T> &v) {
126 m_out << "[";
127 for (unsigned int i = 0; i < v.size(); i++) {
128 if (i > 0) m_out << ',';
129 *this << v[i];
131 m_out << "]";
132 return *this;
135 template<typename T>
136 _OutputStream &operator<< (const std::set<T> &v) {
137 m_out << "[";
138 bool first = true;
139 for (T el: v) {
140 if (first) {
141 first = false;
142 } else {
143 m_out << ',';
145 *this << el;
147 m_out << "]";
148 return *this;
151 // TODO: std::map and std::unordered_map should share
152 // the same function...
154 template<typename K, typename T, typename C>
155 _OutputStream &operator<< (const std::map<K, T, C> &v) {
156 m_out << "{";
157 for (auto iter = v.begin(); iter != v.end(); ++iter) {
158 if (iter != v.begin()) m_out << ',';
159 *this << Name(iter->first);
160 *this << iter->second;
162 m_out << "}\n";
163 return *this;
166 template<typename K, typename T, typename H, typename E>
167 _OutputStream &operator<< (const hphp_hash_map<K, T, H, E> &v) {
168 m_out << "{";
169 for (auto iter = v.begin(); iter != v.end(); ++iter) {
170 if (iter != v.begin()) m_out << ',';
171 *this << Name(iter->first);
172 *this << iter->second;
174 m_out << "}\n";
175 return *this;
178 private:
179 std::ostream &m_out;
181 std::ostream &raw() { return m_out;}
183 friend struct _MapStream<Type>;
184 friend struct _ListStream<Type>;
187 template <typename Type>
188 struct _MapStream {
189 explicit _MapStream(_OutputStream<Type> &jout)
190 : m_out(jout.raw()), m_jout(jout), m_first(true) {}
192 template<typename T>
193 _MapStream &add(const std::string &n, T v) {
194 init(n);
195 m_jout << v;
196 return *this;
199 _MapStream &add(const std::string &n) {
200 init(n);
201 return *this;
204 void done() {
205 if (m_first) {
206 m_out << "{";
208 m_out << "}\n";
211 private:
212 std::ostream &m_out;
213 _OutputStream<Type> &m_jout;
214 bool m_first;
216 void init(const std::string &n) {
217 if (m_first) {
218 m_out << "{";
219 m_first = false;
220 } else {
221 m_out << ",";
223 m_jout << Name(n);
227 template <typename Type>
228 struct _ListStream {
229 explicit _ListStream(_OutputStream<Type> &jout)
230 : m_out(jout.raw()), m_jout(jout), m_first(true) {}
232 void next() {
233 if (m_first) {
234 m_out << "[";
235 m_first = false;
236 } else {
237 m_out << ",";
241 template<typename T>
242 _ListStream &operator<< (T &v) {
243 next();
244 m_jout << v;
245 return *this;
248 void done() {
249 if (m_first) {
250 m_out << "[";
252 m_out << "]\n";
255 private:
256 std::ostream &m_out;
257 _OutputStream<Type> &m_jout;
258 bool m_first;
261 ///////////////////////////////////////////////////////////////////////////////