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/os.h"
13#include "vm/service.h"
14#include "vm/token_position.h"
15
16namespace dart {
17
18class Array;
19class Breakpoint;
20class BreakpointLocation;
21class Field;
22class GrowableObjectArray;
23class Instance;
24class JSONArray;
25class JSONObject;
26class MessageQueue;
27class Metric;
28class Object;
29class Script;
30class ServiceEvent;
31class String;
32class TimelineEvent;
33class TimelineEventBlock;
34class Thread;
35class ThreadRegistry;
36class Zone;
37
38// Keep this enum in sync with:
39//
40// - runtime/vm/service/vmservice.dart
41// - runtime/observatory/lib/src/service/object.dart
42// - pkg/dds/lib/src/rpc_error_codes.dart
43//
44enum JSONRpcErrorCode {
45 kParseError = -32700,
46 kInvalidRequest = -32600,
47 kMethodNotFound = -32601,
48 kInvalidParams = -32602,
49 kInternalError = -32603,
50
51 kExtensionError = -32000,
52
53 kFeatureDisabled = 100,
54 kCannotAddBreakpoint = 102,
55 kStreamAlreadySubscribed = 103,
56 kStreamNotSubscribed = 104,
57 kIsolateMustBeRunnable = 105,
58 kIsolateMustBePaused = 106,
59 kCannotResume = 107,
60 kIsolateIsReloading = 108,
61 kIsolateReloadBarred = 109,
62 kIsolateMustHaveReloaded = 110,
63 kServiceAlreadyRegistered = 111,
64 kServiceDisappeared = 112,
65 kExpressionCompilationError = 113,
66 kInvalidTimelineRequest = 114,
67
68 // Experimental (used in private rpcs).
69 kFileSystemAlreadyExists = 1001,
70 kFileSystemDoesNotExist = 1002,
71 kFileDoesNotExist = 1003,
72};
73
74// Builds on JSONWriter to provide support for serializing various objects
75// used in the VM service protocol.
76class JSONStream : ValueObject {
77 public:
78 explicit JSONStream(intptr_t buf_size = 256);
79
80 void Setup(Zone* zone,
81 Dart_Port reply_port,
82 const Instance& seq,
83 const String& method,
84 const Array& param_keys,
85 const Array& param_values,
86 bool parameters_are_dart_objects = false);
87 void SetupError();
88
89 void PrintError(intptr_t code, const char* details_format, ...)
90 PRINTF_ATTRIBUTE(3, 4);
91
92 void PostReply();
93
94 void set_id_zone(ServiceIdZone* id_zone) { id_zone_ = id_zone; }
95 ServiceIdZone* id_zone() { return id_zone_; }
96
97 TextBuffer* buffer() { return writer_.buffer(); }
98 const char* ToCString() { return writer_.ToCString(); }
99
100 void Steal(char** buffer, intptr_t* buffer_length) {
101 writer_.Steal(buffer, buffer_length);
102 }
103
104 void set_reply_port(Dart_Port port);
105
106 bool include_private_members() const { return include_private_members_; }
107 void set_include_private_members(bool include_private_members) {
108 include_private_members_ = include_private_members;
109 }
110
111 bool IsAllowableKey(const char* key) {
112 if (include_private_members_) {
113 return true;
114 }
115 return *key != '_';
116 }
117
118 void SetParams(const char** param_keys,
119 const char** param_values,
120 intptr_t num_params);
121
122 Dart_Port reply_port() const { return reply_port_; }
123
124 intptr_t NumObjectParameters() const;
125 ObjectPtr GetObjectParameterKey(intptr_t i) const;
126 ObjectPtr GetObjectParameterValue(intptr_t i) const;
127 ObjectPtr LookupObjectParam(const char* key) const;
128
129 intptr_t num_params() const { return num_params_; }
130 const char* GetParamKey(intptr_t i) const { return param_keys_[i]; }
131 const char* GetParamValue(intptr_t i) const { return param_values_[i]; }
132
133 const char* LookupParam(const char* key) const;
134
135 bool HasParam(const char* key) const;
136
137 // Returns true if there is an param with key and value, false
138 // otherwise.
139 bool ParamIs(const char* key, const char* value) const;
140
141 const char* method() const { return method_; }
142 const char** param_keys() const { return param_keys_; }
143 const char** param_values() const { return param_values_; }
144
145 void set_offset(intptr_t value) {
146 ASSERT(value > 0);
147 offset_ = value;
148 }
149
150 void set_count(intptr_t value) {
151 ASSERT(value > 0);
152 count_ = value;
153 }
154
155 void ComputeOffsetAndCount(intptr_t length,
156 intptr_t* offset,
157 intptr_t* count);
158
159 // Append |buffer| to the stream.
160 void AppendBytes(const uint8_t* buffer, intptr_t buffer_length) {
161 writer_.AppendBytes(buffer, buffer_length);
162 }
163
164 // Append |serialized_object| to the stream.
165 void AppendSerializedObject(const char* serialized_object) {
166 writer_.AppendSerializedObject(serialized_object);
167 }
168
169 // Append |serialized_object| to the stream with |property_name|.
170 void AppendSerializedObject(const char* property_name,
171 const char* serialized_object) {
172 writer_.AppendSerializedObject(property_name, serialized_object);
173 }
174
175 void PrintCommaIfNeeded() { writer_.PrintCommaIfNeeded(); }
176 JSONWriter* writer() { return &writer_; }
177
178 private:
179 void Clear() { writer_.Clear(); }
180
181 void PostNullReply(Dart_Port port);
182
183 void OpenObject(const char* property_name = nullptr) {
184 if (ignore_object_depth_ > 0 ||
185 (property_name != nullptr && !IsAllowableKey(key: property_name))) {
186 ignore_object_depth_++;
187 return;
188 }
189 writer_.OpenObject(property_name);
190 }
191 void CloseObject() {
192 if (ignore_object_depth_ > 0) {
193 ignore_object_depth_--;
194 return;
195 }
196 writer_.CloseObject();
197 }
198 void UncloseObject() {
199 // This should be updated to handle unclosing a private object if we need
200 // to handle that case, which we don't currently.
201 writer_.UncloseObject();
202 }
203
204 void OpenArray(const char* property_name = nullptr) {
205 if (ignore_object_depth_ > 0 ||
206 (property_name != nullptr && !IsAllowableKey(key: property_name))) {
207 ignore_object_depth_++;
208 return;
209 }
210 writer_.OpenArray(property_name);
211 }
212 void CloseArray() {
213 if (ignore_object_depth_ > 0) {
214 ignore_object_depth_--;
215 return;
216 }
217 writer_.CloseArray();
218 }
219
220 // Append the Base64 encoding of |bytes| to the stream.
221 //
222 // Beware that padding characters are added when |length| is not a multiple of
223 // three. Padding is only valid at the end of Base64 strings, so you must be
224 // careful when trying to populate a single Base64 string with multiple calls
225 // to this method. |JSONBase64String| should be used for that use-case,
226 // because it handles padding management.
227 void AppendBytesInBase64(const uint8_t* bytes, intptr_t length) {
228 writer_.AppendBytesInBase64(bytes, length);
229 }
230 void PrintValueNull() { writer_.PrintValueNull(); }
231 void PrintValueBool(bool b) { writer_.PrintValueBool(b); }
232 void PrintValue(intptr_t i) { writer_.PrintValue(i); }
233 void PrintValue64(int64_t i) { writer_.PrintValue64(i); }
234 void PrintValueTimeMillis(int64_t millis) { writer_.PrintValue64(i: millis); }
235 void PrintValueTimeMicros(int64_t micros) { writer_.PrintValue64(i: micros); }
236 void PrintValue(double d) { writer_.PrintValue(d); }
237 void PrintValueBase64(const uint8_t* bytes, intptr_t length) {
238 writer_.PrintValueBase64(bytes, length);
239 }
240 void PrintValue(const char* s) { writer_.PrintValue(s); }
241 void PrintValueNoEscape(const char* s) { writer_.PrintValueNoEscape(s); }
242 bool PrintValueStr(const String& s, intptr_t offset, intptr_t count) {
243 return writer_.PrintValueStr(s, offset, count);
244 }
245 void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
246 void VPrintfValue(const char* format, va_list args) {
247 writer_.VPrintfValue(format, args);
248 }
249
250 void PrintValue(const Object& o, bool ref = true);
251 void PrintValue(Breakpoint* bpt);
252 void PrintValue(TokenPosition tp);
253 void PrintValue(const ServiceEvent* event);
254 void PrintValue(Metric* metric);
255 void PrintValue(MessageQueue* queue);
256 void PrintValue(Isolate* isolate, bool ref = true);
257 void PrintValue(IsolateGroup* isolate, bool ref = true);
258 void PrintValue(const TimelineEvent* timeline_event);
259 void PrintValue(const TimelineEventBlock* timeline_event_block);
260 void PrintValueVM(bool ref = true);
261
262 void PrintServiceId(const Object& o);
263
264#define PRIVATE_NAME_CHECK() \
265 if (!IsAllowableKey(name) || ignore_object_depth_ > 0) { \
266 return; \
267 }
268
269 void PrintPropertyBool(const char* name, bool b) {
270 PRIVATE_NAME_CHECK();
271 writer_.PrintPropertyBool(name, b);
272 }
273 void PrintProperty(const char* name, intptr_t i) {
274 PRIVATE_NAME_CHECK();
275 writer_.PrintProperty(name, i);
276 }
277 void PrintProperty64(const char* name, int64_t i) {
278 PRIVATE_NAME_CHECK();
279 writer_.PrintProperty64(name, i);
280 }
281 void PrintPropertyTimeMillis(const char* name, int64_t millis) {
282 PRIVATE_NAME_CHECK();
283 writer_.PrintProperty64(name, i: millis);
284 }
285 void PrintPropertyTimeMicros(const char* name, int64_t micros) {
286 PRIVATE_NAME_CHECK();
287 writer_.PrintProperty64(name, i: micros);
288 }
289 void PrintProperty(const char* name, double d) {
290 PRIVATE_NAME_CHECK();
291 writer_.PrintProperty(name, d);
292 }
293 void PrintPropertyBase64(const char* name,
294 const uint8_t* bytes,
295 intptr_t length) {
296 PRIVATE_NAME_CHECK();
297 writer_.PrintPropertyBase64(name, bytes, length);
298 }
299 void PrintProperty(const char* name, const char* s) {
300 PRIVATE_NAME_CHECK();
301 writer_.PrintProperty(name, s);
302 }
303 bool PrintPropertyStr(const char* name,
304 const String& s,
305 intptr_t offset,
306 intptr_t count) {
307 if (!IsAllowableKey(key: name)) {
308 return false;
309 }
310 return writer_.PrintPropertyStr(name, s, offset, count);
311 }
312 void PrintPropertyNoEscape(const char* name, const char* s) {
313 PRIVATE_NAME_CHECK();
314 writer_.PrintPropertyNoEscape(name, s);
315 }
316 void PrintfProperty(const char* name, const char* format, ...)
317 PRINTF_ATTRIBUTE(3, 4);
318 void VPrintfProperty(const char* name, const char* format, va_list args) {
319 PRIVATE_NAME_CHECK();
320 writer_.VPrintfProperty(name, format, args);
321 }
322
323#undef PRIVATE_NAME_CHECK
324
325 void PrintProperty(const char* name, const Object& o, bool ref = true);
326
327 void PrintProperty(const char* name, const ServiceEvent* event);
328 void PrintProperty(const char* name, Breakpoint* bpt);
329 void PrintProperty(const char* name, TokenPosition tp);
330 void PrintProperty(const char* name, Metric* metric);
331 void PrintProperty(const char* name, MessageQueue* queue);
332 void PrintProperty(const char* name, Isolate* isolate);
333 void PrintProperty(const char* name, IsolateGroup* isolate_group);
334 void PrintProperty(const char* name, Zone* zone);
335 void PrintProperty(const char* name, const TimelineEvent* timeline_event);
336 void PrintProperty(const char* name,
337 const TimelineEventBlock* timeline_event_block);
338 void PrintPropertyVM(const char* name, bool ref = true);
339 void PrintPropertyName(const char* name) { writer_.PrintPropertyName(name); }
340
341 void AddEscapedUTF8String(const char* s, intptr_t len) {
342 writer_.AddEscapedUTF8String(s, len);
343 }
344
345 JSONWriter writer_;
346 // Default service id zone.
347 RingServiceIdZone default_id_zone_;
348 ServiceIdZone* id_zone_;
349 Dart_Port reply_port_;
350 Instance* seq_;
351 Array* parameter_keys_;
352 Array* parameter_values_;
353 const char* method_;
354 const char** param_keys_;
355 const char** param_values_;
356 intptr_t num_params_;
357 intptr_t offset_;
358 intptr_t count_;
359 int64_t setup_time_micros_;
360 bool include_private_members_;
361 intptr_t ignore_object_depth_;
362 friend class JSONObject;
363 friend class JSONArray;
364 friend class JSONBase64String;
365 friend class TimelineEvent;
366};
367
368class JSONObject : public ValueObject {
369 public:
370 explicit JSONObject(JSONStream* stream) : stream_(stream) {
371 stream_->OpenObject();
372 }
373 JSONObject(const JSONObject* obj, const char* name) : stream_(obj->stream_) {
374 stream_->OpenObject(property_name: name);
375 }
376 explicit JSONObject(const JSONArray* arr);
377
378 ~JSONObject() { stream_->CloseObject(); }
379
380 void AddServiceId(const Object& o) const { stream_->PrintServiceId(o); }
381
382 void AddFixedServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
383 void AddServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
384
385 void AddLocation(
386 const Script& script,
387 TokenPosition token_pos,
388 TokenPosition end_token_pos = TokenPosition::kNoSource) const;
389
390 void AddLocation(const BreakpointLocation* bpt_loc) const;
391 void AddLocationLine(const Script& script, intptr_t line) const;
392
393 void AddUnresolvedLocation(const BreakpointLocation* bpt_loc) const;
394
395 void AddProperty(const char* name, bool b) const {
396 stream_->PrintPropertyBool(name, b);
397 }
398 void AddProperty(const char* name, intptr_t i) const {
399 stream_->PrintProperty(name, i);
400 }
401 void AddProperty64(const char* name, int64_t i) const {
402 stream_->PrintProperty64(name, i);
403 }
404 void AddPropertyTimeMillis(const char* name, int64_t millis) const {
405 stream_->PrintPropertyTimeMillis(name, millis);
406 }
407 void AddPropertyTimeMicros(const char* name, int64_t micros) const {
408 stream_->PrintPropertyTimeMicros(name, micros);
409 }
410 void AddProperty(const char* name, double d) const {
411 stream_->PrintProperty(name, d);
412 }
413 void AddPropertyBase64(const char* name,
414 const uint8_t* bytes,
415 intptr_t length) const {
416 stream_->PrintPropertyBase64(name, bytes, length);
417 }
418 void AddProperty(const char* name, const char* s) const {
419 stream_->PrintProperty(name, s);
420 }
421 bool AddPropertyStr(const char* name,
422 const String& s,
423 intptr_t offset = 0,
424 intptr_t count = -1) const {
425 return stream_->PrintPropertyStr(name, s, offset, count);
426 }
427 void AddPropertyNoEscape(const char* name, const char* s) const {
428 stream_->PrintPropertyNoEscape(name, s);
429 }
430 void AddProperty(const char* name, const Object& obj, bool ref = true) const {
431 stream_->PrintProperty(name, o: obj, ref);
432 }
433 void AddProperty(const char* name, const ServiceEvent* event) const {
434 stream_->PrintProperty(name, event);
435 }
436 void AddProperty(const char* name, Breakpoint* bpt) const {
437 stream_->PrintProperty(name, bpt);
438 }
439 void AddProperty(const char* name, TokenPosition tp) const {
440 stream_->PrintProperty(name, tp);
441 }
442 void AddProperty(const char* name, Metric* metric) const {
443 stream_->PrintProperty(name, metric);
444 }
445 void AddProperty(const char* name, MessageQueue* queue) const {
446 stream_->PrintProperty(name, queue);
447 }
448 void AddProperty(const char* name, Isolate* isolate) const {
449 stream_->PrintProperty(name, isolate);
450 }
451 void AddProperty(const char* name, IsolateGroup* isolate_group) const {
452 stream_->PrintProperty(name, isolate_group);
453 }
454 void AddProperty(const char* name, Zone* zone) const {
455 stream_->PrintProperty(name, zone);
456 }
457 void AddProperty(const char* name,
458 const TimelineEvent* timeline_event) const {
459 stream_->PrintProperty(name, timeline_event);
460 }
461 void AddProperty(const char* name,
462 const TimelineEventBlock* timeline_event_block) const {
463 stream_->PrintProperty(name, timeline_event_block);
464 }
465 void AddPropertyVM(const char* name, bool ref = true) const {
466 stream_->PrintPropertyVM(name, ref);
467 }
468 void AddPropertyF(const char* name, const char* format, ...) const
469 PRINTF_ATTRIBUTE(3, 4);
470
471 private:
472 JSONStream* stream_;
473
474 friend class JSONArray;
475
476 DISALLOW_ALLOCATION();
477 DISALLOW_COPY_AND_ASSIGN(JSONObject);
478};
479
480class JSONArray : public ValueObject {
481 public:
482 explicit JSONArray(JSONStream* stream) : stream_(stream) {
483 stream_->OpenArray();
484 }
485 JSONArray(const JSONObject* obj, const char* name) : stream_(obj->stream_) {
486 stream_->OpenArray(property_name: name);
487 }
488 explicit JSONArray(const JSONArray* arr) : stream_(arr->stream_) {
489 stream_->OpenArray();
490 }
491 ~JSONArray() { stream_->CloseArray(); }
492
493 void AddValueNull() const { stream_->PrintValueNull(); }
494 void AddValue(bool b) const { stream_->PrintValueBool(b); }
495 void AddValue(intptr_t i) const { stream_->PrintValue(i); }
496 void AddValue64(int64_t i) const { stream_->PrintValue64(i); }
497 void AddValueTimeMillis(int64_t millis) const {
498 stream_->PrintValueTimeMillis(millis);
499 }
500 void AddValueTimeMicros(int64_t micros) const {
501 stream_->PrintValueTimeMicros(micros);
502 }
503 void AddValue(double d) const { stream_->PrintValue(d); }
504 void AddValue(const char* s) const { stream_->PrintValue(s); }
505 void AddValue(const Object& obj, bool ref = true) const {
506 stream_->PrintValue(o: obj, ref);
507 }
508 void AddValue(Isolate* isolate, bool ref = true) const {
509 stream_->PrintValue(isolate, ref);
510 }
511 void AddValue(IsolateGroup* isolate_group, bool ref = true) const {
512 stream_->PrintValue(isolate: isolate_group, ref);
513 }
514 void AddValue(Breakpoint* bpt) const { stream_->PrintValue(bpt); }
515 void AddValue(TokenPosition tp) const { stream_->PrintValue(tp); }
516 void AddValue(const ServiceEvent* event) const { stream_->PrintValue(event); }
517 void AddValue(Metric* metric) const { stream_->PrintValue(metric); }
518 void AddValue(MessageQueue* queue) const { stream_->PrintValue(queue); }
519 void AddValue(const TimelineEvent* timeline_event) const {
520 stream_->PrintValue(timeline_event);
521 }
522 void AddValue(const TimelineEventBlock* timeline_event_block) const {
523 stream_->PrintValue(timeline_event_block);
524 }
525 void AddValueVM(bool ref = true) const { stream_->PrintValueVM(ref); }
526 void AddValueF(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
527
528 private:
529 JSONStream* stream_;
530
531 friend class JSONObject;
532
533 DISALLOW_ALLOCATION();
534 DISALLOW_COPY_AND_ASSIGN(JSONArray);
535};
536
537class JSONBase64String : public ValueObject {
538 public:
539 explicit JSONBase64String(JSONStream* stream)
540 : stream_(stream), queued_bytes_(), num_queued_bytes_(0) {
541 stream_->AppendBytes(buffer: reinterpret_cast<const uint8_t*>("\""), buffer_length: 1);
542 }
543 ~JSONBase64String() {
544 stream_->AppendBytesInBase64(bytes: queued_bytes_, length: num_queued_bytes_);
545 stream_->AppendBytes(buffer: reinterpret_cast<const uint8_t*>("\""), buffer_length: 1);
546 }
547
548 void AppendBytes(const uint8_t* bytes, intptr_t length);
549
550 private:
551 JSONStream* stream_;
552 uint8_t queued_bytes_[3];
553 intptr_t num_queued_bytes_;
554
555 DISALLOW_ALLOCATION();
556 DISALLOW_COPY_AND_ASSIGN(JSONBase64String);
557};
558
559} // namespace dart
560
561#endif // RUNTIME_VM_JSON_STREAM_H_
562

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com

source code of flutter_engine/third_party/dart/runtime/vm/json_stream.h