1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_JSON_STREAM_H_
6#define RUNTIME_VM_JSON_STREAM_H_
7
8#include "include/dart_api.h" // for Dart_Port
9#include "platform/allocation.h"
10#include "platform/text_buffer.h"
11#include "vm/json_writer.h"
12#include "vm/service.h"
13#include "vm/token_position.h"
14
15namespace dart {
16
17class Array;
18class Breakpoint;
19class BreakpointLocation;
20class Field;
21class GrowableObjectArray;
22class Instance;
23class JSONArray;
24class JSONObject;
25class MessageQueue;
26class Metric;
27class Object;
28class Script;
29class ServiceEvent;
30class String;
31class TimelineEvent;
32class TimelineEventBlock;
33class Thread;
34class ThreadRegistry;
35class Zone;
36
37// Keep this enum in sync with:
38//
39// - runtime/vm/service/vmservice.dart
40// - runtime/observatory/lib/src/service/object.dart
41// - pkg/dds/lib/src/rpc_error_codes.dart
42//
43enum JSONRpcErrorCode {
44 kParseError = -32700,
45 kInvalidRequest = -32600,
46 kMethodNotFound = -32601,
47 kInvalidParams = -32602,
48 kInternalError = -32603,
49
50 kExtensionError = -32000,
51
52 kFeatureDisabled = 100,
53 kCannotAddBreakpoint = 102,
54 kStreamAlreadySubscribed = 103,
55 kStreamNotSubscribed = 104,
56 kIsolateMustBeRunnable = 105,
57 kIsolateMustBePaused = 106,
58 kCannotResume = 107,
59 kIsolateIsReloading = 108,
60 kIsolateReloadBarred = 109,
61 kIsolateMustHaveReloaded = 110,
62 kServiceAlreadyRegistered = 111,
63 kServiceDisappeared = 112,
64 kExpressionCompilationError = 113,
65 kInvalidTimelineRequest = 114,
66
67 // Experimental (used in private rpcs).
68 kFileSystemAlreadyExists = 1001,
69 kFileSystemDoesNotExist = 1002,
70 kFileDoesNotExist = 1003,
71};
72
73// Builds on JSONWriter to provide support for serializing various objects
74// used in the VM service protocol.
75class JSONStream : ValueObject {
76 public:
77 explicit JSONStream(intptr_t buf_size = 256);
78
79 void Setup(Zone* zone,
80 Dart_Port reply_port,
81 const Instance& seq,
82 const String& method,
83 const Array& param_keys,
84 const Array& param_values,
85 bool parameters_are_dart_objects = false);
86 void SetupError();
87
88 void PrintError(intptr_t code, const char* details_format, ...)
89 PRINTF_ATTRIBUTE(3, 4);
90
91 void PostReply();
92
93 void set_id_zone(ServiceIdZone* id_zone) { id_zone_ = id_zone; }
94 ServiceIdZone* id_zone() { return id_zone_; }
95
96 TextBuffer* buffer() { return writer_.buffer(); }
97 const char* ToCString() { return writer_.ToCString(); }
98
99 void Steal(char** buffer, intptr_t* buffer_length) {
100 writer_.Steal(buffer, buffer_length);
101 }
102
103 void set_reply_port(Dart_Port port);
104
105 void SetParams(const char** param_keys,
106 const char** param_values,
107 intptr_t num_params);
108
109 Dart_Port reply_port() const { return reply_port_; }
110
111 intptr_t NumObjectParameters() const;
112 ObjectPtr GetObjectParameterKey(intptr_t i) const;
113 ObjectPtr GetObjectParameterValue(intptr_t i) const;
114 ObjectPtr LookupObjectParam(const char* key) const;
115
116 intptr_t num_params() const { return num_params_; }
117 const char* GetParamKey(intptr_t i) const { return param_keys_[i]; }
118 const char* GetParamValue(intptr_t i) const { return param_values_[i]; }
119
120 const char* LookupParam(const char* key) const;
121
122 bool HasParam(const char* key) const;
123
124 // Returns true if there is an param with key and value, false
125 // otherwise.
126 bool ParamIs(const char* key, const char* value) const;
127
128 const char* method() const { return method_; }
129 const char** param_keys() const { return param_keys_; }
130 const char** param_values() const { return param_values_; }
131
132 void set_offset(intptr_t value) {
133 ASSERT(value > 0);
134 offset_ = value;
135 }
136
137 void set_count(intptr_t value) {
138 ASSERT(value > 0);
139 count_ = value;
140 }
141
142 void ComputeOffsetAndCount(intptr_t length,
143 intptr_t* offset,
144 intptr_t* count);
145
146 // Append |serialized_object| to the stream.
147 void AppendSerializedObject(const char* serialized_object) {
148 writer_.AppendSerializedObject(serialized_object);
149 }
150
151 // Append |buffer| to the stream.
152 void AppendSerializedObject(const uint8_t* buffer, intptr_t buffer_length) {
153 writer_.AppendSerializedObject(buffer, buffer_length);
154 }
155
156 // Append |serialized_object| to the stream with |property_name|.
157 void AppendSerializedObject(const char* property_name,
158 const char* serialized_object) {
159 writer_.AppendSerializedObject(property_name, serialized_object);
160 }
161
162 void PrintCommaIfNeeded() { writer_.PrintCommaIfNeeded(); }
163
164 private:
165 void Clear() { writer_.Clear(); }
166
167 void PostNullReply(Dart_Port port);
168
169 void OpenObject(const char* property_name = NULL) {
170 writer_.OpenObject(property_name);
171 }
172 void CloseObject() { writer_.CloseObject(); }
173 void UncloseObject() { writer_.UncloseObject(); }
174
175 void OpenArray(const char* property_name = NULL) {
176 writer_.OpenArray(property_name);
177 }
178 void CloseArray() { writer_.CloseArray(); }
179
180 void PrintValueNull() { writer_.PrintValueNull(); }
181 void PrintValueBool(bool b) { writer_.PrintValueBool(b); }
182 void PrintValue(intptr_t i) { writer_.PrintValue(i); }
183 void PrintValue64(int64_t i) { writer_.PrintValue64(i); }
184 void PrintValueTimeMillis(int64_t millis) { writer_.PrintValue64(millis); }
185 void PrintValueTimeMicros(int64_t micros) { writer_.PrintValue64(micros); }
186 void PrintValue(double d) { writer_.PrintValue(d); }
187 void PrintValueBase64(const uint8_t* bytes, intptr_t length) {
188 writer_.PrintValueBase64(bytes, length);
189 }
190 void PrintValue(const char* s) { writer_.PrintValue(s); }
191 void PrintValueNoEscape(const char* s) { writer_.PrintValueNoEscape(s); }
192 bool PrintValueStr(const String& s, intptr_t offset, intptr_t count) {
193 return writer_.PrintValueStr(s, offset, count);
194 }
195 void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
196 void VPrintfValue(const char* format, va_list args) {
197 writer_.VPrintfValue(format, args);
198 }
199
200 void PrintValue(const Object& o, bool ref = true);
201 void PrintValue(Breakpoint* bpt);
202 void PrintValue(TokenPosition tp);
203 void PrintValue(const ServiceEvent* event);
204 void PrintValue(Metric* metric);
205 void PrintValue(MessageQueue* queue);
206 void PrintValue(Isolate* isolate, bool ref = true);
207 void PrintValue(IsolateGroup* isolate, bool ref = true);
208 void PrintValue(ThreadRegistry* reg);
209 void PrintValue(Thread* thread);
210 void PrintValue(const TimelineEvent* timeline_event);
211 void PrintValue(const TimelineEventBlock* timeline_event_block);
212 void PrintValueVM(bool ref = true);
213
214 void PrintServiceId(const Object& o);
215
216 void PrintPropertyBool(const char* name, bool b) {
217 writer_.PrintPropertyBool(name, b);
218 }
219 void PrintProperty(const char* name, intptr_t i) {
220 writer_.PrintProperty(name, i);
221 }
222 void PrintProperty64(const char* name, int64_t i) {
223 writer_.PrintProperty64(name, i);
224 }
225 void PrintPropertyTimeMillis(const char* name, int64_t millis) {
226 writer_.PrintProperty64(name, millis);
227 }
228 void PrintPropertyTimeMicros(const char* name, int64_t micros) {
229 writer_.PrintProperty64(name, micros);
230 }
231 void PrintProperty(const char* name, double d) {
232 writer_.PrintProperty(name, d);
233 }
234 void PrintPropertyBase64(const char* name,
235 const uint8_t* bytes,
236 intptr_t length) {
237 writer_.PrintPropertyBase64(name, bytes, length);
238 }
239 void PrintProperty(const char* name, const char* s) {
240 writer_.PrintProperty(name, s);
241 }
242 bool PrintPropertyStr(const char* name,
243 const String& s,
244 intptr_t offset,
245 intptr_t count) {
246 return writer_.PrintPropertyStr(name, s, offset, count);
247 }
248 void PrintPropertyNoEscape(const char* name, const char* s) {
249 writer_.PrintPropertyNoEscape(name, s);
250 }
251 void PrintfProperty(const char* name, const char* format, ...)
252 PRINTF_ATTRIBUTE(3, 4);
253 void VPrintfProperty(const char* name, const char* format, va_list args) {
254 writer_.VPrintfProperty(name, format, args);
255 }
256 void PrintProperty(const char* name, const Object& o, bool ref = true);
257
258 void PrintProperty(const char* name, const ServiceEvent* event);
259 void PrintProperty(const char* name, Breakpoint* bpt);
260 void PrintProperty(const char* name, TokenPosition tp);
261 void PrintProperty(const char* name, Metric* metric);
262 void PrintProperty(const char* name, MessageQueue* queue);
263 void PrintProperty(const char* name, Isolate* isolate);
264 void PrintProperty(const char* name, ThreadRegistry* reg);
265 void PrintProperty(const char* name, Thread* thread);
266 void PrintProperty(const char* name, Zone* zone);
267 void PrintProperty(const char* name, const TimelineEvent* timeline_event);
268 void PrintProperty(const char* name,
269 const TimelineEventBlock* timeline_event_block);
270 void PrintPropertyVM(const char* name, bool ref = true);
271 void PrintPropertyName(const char* name) { writer_.PrintPropertyName(name); }
272
273 void AddEscapedUTF8String(const char* s, intptr_t len) {
274 writer_.AddEscapedUTF8String(s, len);
275 }
276
277 JSONWriter writer_;
278 // Default service id zone.
279 RingServiceIdZone default_id_zone_;
280 ServiceIdZone* id_zone_;
281 Dart_Port reply_port_;
282 Instance* seq_;
283 Array* parameter_keys_;
284 Array* parameter_values_;
285 const char* method_;
286 const char** param_keys_;
287 const char** param_values_;
288 intptr_t num_params_;
289 intptr_t offset_;
290 intptr_t count_;
291 int64_t setup_time_micros_;
292
293 friend class JSONObject;
294 friend class JSONArray;
295 friend class TimelineEvent;
296};
297
298class JSONObject : public ValueObject {
299 public:
300 explicit JSONObject(JSONStream* stream) : stream_(stream) {
301 stream_->OpenObject();
302 }
303 JSONObject(const JSONObject* obj, const char* name) : stream_(obj->stream_) {
304 stream_->OpenObject(name);
305 }
306 explicit JSONObject(const JSONArray* arr);
307
308 ~JSONObject() { stream_->CloseObject(); }
309
310 void AddServiceId(const Object& o) const { stream_->PrintServiceId(o); }
311
312 void AddFixedServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
313 void AddServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
314
315 void AddLocation(
316 const Script& script,
317 TokenPosition token_pos,
318 TokenPosition end_token_pos = TokenPosition::kNoSource) const;
319
320 void AddLocation(const BreakpointLocation* bpt_loc) const;
321
322 void AddUnresolvedLocation(const BreakpointLocation* bpt_loc) const;
323
324 void AddProperty(const char* name, bool b) const {
325 stream_->PrintPropertyBool(name, b);
326 }
327 void AddProperty(const char* name, intptr_t i) const {
328 stream_->PrintProperty(name, i);
329 }
330 void AddProperty64(const char* name, int64_t i) const {
331 stream_->PrintProperty64(name, i);
332 }
333 void AddPropertyTimeMillis(const char* name, int64_t millis) const {
334 stream_->PrintPropertyTimeMillis(name, millis);
335 }
336 void AddPropertyTimeMicros(const char* name, int64_t micros) const {
337 stream_->PrintPropertyTimeMicros(name, micros);
338 }
339 void AddProperty(const char* name, double d) const {
340 stream_->PrintProperty(name, d);
341 }
342 void AddPropertyBase64(const char* name,
343 const uint8_t* bytes,
344 intptr_t length) const {
345 stream_->PrintPropertyBase64(name, bytes, length);
346 }
347 void AddProperty(const char* name, const char* s) const {
348 stream_->PrintProperty(name, s);
349 }
350 bool AddPropertyStr(const char* name,
351 const String& s,
352 intptr_t offset = 0,
353 intptr_t count = -1) const {
354 return stream_->PrintPropertyStr(name, s, offset, count);
355 }
356 void AddPropertyNoEscape(const char* name, const char* s) const {
357 stream_->PrintPropertyNoEscape(name, s);
358 }
359 void AddProperty(const char* name, const Object& obj, bool ref = true) const {
360 stream_->PrintProperty(name, obj, ref);
361 }
362 void AddProperty(const char* name, const ServiceEvent* event) const {
363 stream_->PrintProperty(name, event);
364 }
365 void AddProperty(const char* name, Breakpoint* bpt) const {
366 stream_->PrintProperty(name, bpt);
367 }
368 void AddProperty(const char* name, TokenPosition tp) const {
369 stream_->PrintProperty(name, tp);
370 }
371 void AddProperty(const char* name, Metric* metric) const {
372 stream_->PrintProperty(name, metric);
373 }
374 void AddProperty(const char* name, MessageQueue* queue) const {
375 stream_->PrintProperty(name, queue);
376 }
377 void AddProperty(const char* name, Isolate* isolate) const {
378 stream_->PrintProperty(name, isolate);
379 }
380 void AddProperty(const char* name, ThreadRegistry* reg) const {
381 stream_->PrintProperty(name, reg);
382 }
383 void AddProperty(const char* name, Thread* thread) const {
384 stream_->PrintProperty(name, thread);
385 }
386 void AddProperty(const char* name, Zone* zone) const {
387 stream_->PrintProperty(name, zone);
388 }
389 void AddProperty(const char* name,
390 const TimelineEvent* timeline_event) const {
391 stream_->PrintProperty(name, timeline_event);
392 }
393 void AddProperty(const char* name,
394 const TimelineEventBlock* timeline_event_block) const {
395 stream_->PrintProperty(name, timeline_event_block);
396 }
397 void AddPropertyVM(const char* name, bool ref = true) const {
398 stream_->PrintPropertyVM(name, ref);
399 }
400 void AddPropertyF(const char* name, const char* format, ...) const
401 PRINTF_ATTRIBUTE(3, 4);
402
403 private:
404 JSONStream* stream_;
405
406 friend class JSONArray;
407
408 DISALLOW_ALLOCATION();
409 DISALLOW_COPY_AND_ASSIGN(JSONObject);
410};
411
412class JSONArray : public ValueObject {
413 public:
414 explicit JSONArray(JSONStream* stream) : stream_(stream) {
415 stream_->OpenArray();
416 }
417 JSONArray(const JSONObject* obj, const char* name) : stream_(obj->stream_) {
418 stream_->OpenArray(name);
419 }
420 explicit JSONArray(const JSONArray* arr) : stream_(arr->stream_) {
421 stream_->OpenArray();
422 }
423 ~JSONArray() { stream_->CloseArray(); }
424
425 void AddValueNull() const { stream_->PrintValueNull(); }
426 void AddValue(bool b) const { stream_->PrintValueBool(b); }
427 void AddValue(intptr_t i) const { stream_->PrintValue(i); }
428 void AddValue64(int64_t i) const { stream_->PrintValue64(i); }
429 void AddValueTimeMillis(int64_t millis) const {
430 stream_->PrintValueTimeMillis(millis);
431 }
432 void AddValueTimeMicros(int64_t micros) const {
433 stream_->PrintValueTimeMicros(micros);
434 }
435 void AddValue(double d) const { stream_->PrintValue(d); }
436 void AddValue(const char* s) const { stream_->PrintValue(s); }
437 void AddValue(const Object& obj, bool ref = true) const {
438 stream_->PrintValue(obj, ref);
439 }
440 void AddValue(Isolate* isolate, bool ref = true) const {
441 stream_->PrintValue(isolate, ref);
442 }
443 void AddValue(IsolateGroup* isolate_group, bool ref = true) const {
444 stream_->PrintValue(isolate_group, ref);
445 }
446 void AddValue(ThreadRegistry* reg) const { stream_->PrintValue(reg); }
447 void AddValue(Thread* thread) const { stream_->PrintValue(thread); }
448 void AddValue(Breakpoint* bpt) const { stream_->PrintValue(bpt); }
449 void AddValue(TokenPosition tp) const { stream_->PrintValue(tp); }
450 void AddValue(const ServiceEvent* event) const { stream_->PrintValue(event); }
451 void AddValue(Metric* metric) const { stream_->PrintValue(metric); }
452 void AddValue(MessageQueue* queue) const { stream_->PrintValue(queue); }
453 void AddValue(const TimelineEvent* timeline_event) const {
454 stream_->PrintValue(timeline_event);
455 }
456 void AddValue(const TimelineEventBlock* timeline_event_block) const {
457 stream_->PrintValue(timeline_event_block);
458 }
459 void AddValueVM(bool ref = true) const { stream_->PrintValueVM(ref); }
460 void AddValueF(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
461
462 private:
463 JSONStream* stream_;
464
465 friend class JSONObject;
466
467 DISALLOW_ALLOCATION();
468 DISALLOW_COPY_AND_ASSIGN(JSONArray);
469};
470
471} // namespace dart
472
473#endif // RUNTIME_VM_JSON_STREAM_H_
474