Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: lib/protobuf/runtime/GeneratedMessage.dart

Issue 10595002: Protocol Buffer runtime library and 'protoc' plugin (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Work around http://code.google.com/p/dart/issues/detail?id=3806 Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/protobuf/runtime/FieldInfo.dart ('k') | lib/protobuf/runtime/ImmutableList.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, 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 class GeneratedMessage implements Message, Hashable {
6
7 BuilderInfo _builderInfo;
8 Map<int, Dynamic> _fieldValues;
9 int _memoizedHashCode = -1;
10 int _memoizedIsInitialized = -1;
11 int _memoizedSerializedSize = -1;
12 Map<int, int> _serializedSize;
13 Map<int, Extension> _extensions;
14 UnknownFieldSet _unknownFields;
15
16 static GeneratedMessage parseBuffer(Builder builder, List<int> input,
17 [ExtensionRegistry extensionRegistry]) {
18 extensionRegistry = extensionRegistry == null ?
19 ExtensionRegistry.EMPTY_REGISTRY : extensionRegistry;
20 return builder.mergeFromBuffer(input, extensionRegistry).buildParsed();
21 }
22
23 static Future<GeneratedMessage> parseStream(Builder builder,
24 InputStream input, [ExtensionRegistry extensionRegistry]) {
25 extensionRegistry = extensionRegistry == null ?
26 ExtensionRegistry.EMPTY_REGISTRY : extensionRegistry;
27 return builder.mergeFromStream(input, extensionRegistry)
28 .transform((var _) => builder.buildParsed());
29 }
30
31 GeneratedMessage(Builder builder)
32 : _builderInfo = builder.info_,
33 _fieldValues = new Map<int, Dynamic>(),
34 _serializedSize = new Map<int, int>(),
35 _unknownFields = builder.unknownFields;
36
37 bool operator ==(Object o) {
38 if (!(o is GeneratedMessage)){
39 return false;
40 }
41 GeneratedMessage om = o;
42 if (om._builderInfo != _builderInfo) {
43 return false;
44 }
45
46 if (_fieldValues.length != om._fieldValues.length) {
47 return false;
48 }
49
50 // because lengths are equal, sufficient to test inclusion in 1 direction.
51 for (int key in _fieldValues.getKeys()) {
52 if (!om._fieldValues.containsKey(key) ||
53 _fieldValues[key] != om._fieldValues[key]) {
54 return false;
55 }
56 }
57 if (om._unknownFields != _unknownFields) return false;
58 return true;
59 }
60
61 bool extensionsAreInitialized() {
62 return true; // fixme
63 }
64
65 Dynamic getField(int tagNumber) {
66 var value = _fieldValues[tagNumber];
67 // Initialize the field
68 if (value === null) {
69 var defaultFunc = _builderInfo.makeDefault(tagNumber);
70 if (defaultFunc != null) {
71 value = defaultFunc();
72 }
73 }
74 return value;
75 }
76
77 int _getFieldType(int tagNumber) {
78 int fieldType = _builderInfo.fieldType(tagNumber);
79 if (fieldType == null) {
80 fieldType = _extensions[tagNumber].type;
81 }
82 return fieldType;
83 }
84
85 // Shorthand for getField
86 Dynamic g_(int tagNumber) => getField(tagNumber);
87
88 int getSerializedSize() {
89 if (_memoizedSerializedSize != -1) return _memoizedSerializedSize;
90 int size = 0;
91
92 for (int tagNumber in _fieldValues.getKeys()) {
93 var fieldValue = _fieldValues[tagNumber];
94 int fieldType = _getFieldType(tagNumber) & ~Builder._REQUIRED_BIT;
95 size += _computeSize(tagNumber, fieldType, fieldValue);
96 }
97
98 size += unknownFields.getSerializedSize();
99 _memoizedSerializedSize = size;
100 return size;
101 }
102
103 int _computeSize(int tagNumber, int fieldType, var fieldValue) {
104 int size = 0;
105 switch (fieldType) {
106 case Builder._OPTIONAL_BOOL:
107 return CodedBufferWriter.computeBoolSize(tagNumber, fieldValue);
108 case Builder._OPTIONAL_BYTES:
109 return CodedBufferWriter.computeBytesSize(tagNumber, fieldValue);
110 case Builder._OPTIONAL_STRING:
111 return CodedBufferWriter.computeStringSize(tagNumber, fieldValue);
112 case Builder._OPTIONAL_FLOAT:
113 return CodedBufferWriter.computeFloatSize(tagNumber, fieldValue);
114 case Builder._OPTIONAL_DOUBLE:
115 return CodedBufferWriter.computeDoubleSize(tagNumber, fieldValue);
116 case Builder._OPTIONAL_ENUM:
117 return CodedBufferWriter.computeEnumSize(tagNumber, fieldValue.value);
118 case Builder._OPTIONAL_GROUP:
119 return CodedBufferWriter.computeGroupSize(tagNumber, fieldValue);
120 case Builder._OPTIONAL_INT32:
121 return CodedBufferWriter.computeInt32Size(tagNumber, fieldValue);
122 case Builder._OPTIONAL_INT64:
123 return CodedBufferWriter.computeInt64Size(tagNumber, fieldValue);
124 case Builder._OPTIONAL_SINT32:
125 return CodedBufferWriter.computeSint32Size(tagNumber, fieldValue);
126 case Builder._OPTIONAL_SINT64:
127 return CodedBufferWriter.computeSint64Size(tagNumber, fieldValue);
128 case Builder._OPTIONAL_UINT32:
129 return CodedBufferWriter.computeUint32Size(tagNumber, fieldValue);
130 case Builder._OPTIONAL_UINT64:
131 return CodedBufferWriter.computeUint64Size(tagNumber, fieldValue);
132 case Builder._OPTIONAL_FIXED32:
133 return CodedBufferWriter.computeFixed32Size(tagNumber, fieldValue);
134 case Builder._OPTIONAL_FIXED64:
135 return CodedBufferWriter.computeFixed64Size(tagNumber, fieldValue);
136 case Builder._OPTIONAL_SFIXED32:
137 return CodedBufferWriter.computeSfixed32Size(tagNumber, fieldValue);
138 case Builder._OPTIONAL_SFIXED64:
139 return CodedBufferWriter.computeSfixed64Size(tagNumber, fieldValue);
140 case Builder._OPTIONAL_MESSAGE:
141 return CodedBufferWriter.computeMessageSize(tagNumber, fieldValue);
142 case Builder._REPEATED_BOOL:
143 for (bool val in fieldValue) {
144 size += CodedBufferWriter.computeBoolSize(tagNumber, val);
145 }
146 return size;
147 case Builder._REPEATED_BYTES:
148 List<List<int>> list = fieldValue;
149 for (List<int> val in list) {
150 size += CodedBufferWriter.computeBytesSize(tagNumber, val);
151 }
152 return size;
153 case Builder._REPEATED_STRING:
154 List<String> list = fieldValue;
155 for (String val in list) {
156 size += CodedBufferWriter.computeStringSize(tagNumber, val);
157 }
158 return size;
159 case Builder._REPEATED_FLOAT:
160 List<double> list = fieldValue;
161 for (double val in list) {
162 size += CodedBufferWriter.computeFloatSize(tagNumber, val);
163 }
164 return size;
165 case Builder._REPEATED_DOUBLE:
166 List<double> list = fieldValue;
167 for (double val in list) {
168 size += CodedBufferWriter.computeDoubleSize(tagNumber, val);
169 }
170 return size;
171 case Builder._REPEATED_ENUM:
172 for (var val in fieldValue) {
173 size += CodedBufferWriter.computeEnumSize(tagNumber, val.value);
174 }
175 return size;
176 case Builder._REPEATED_GROUP:
177 for (var val in fieldValue) {
178 size += CodedBufferWriter.computeGroupSize(tagNumber, val);
179 }
180 return size;
181 case Builder._REPEATED_INT32:
182 List<int> list = fieldValue;
183 for (int val in list) {
184 size += CodedBufferWriter.computeInt32Size(tagNumber, val);
185 }
186 return size;
187 case Builder._REPEATED_INT64:
188 List<int> list = fieldValue;
189 for (int val in list) {
190 size += CodedBufferWriter.computeInt64Size(tagNumber, val);
191 }
192 return size;
193 case Builder._REPEATED_SINT32:
194 List<int> list = fieldValue;
195 for (int val in list) {
196 size += CodedBufferWriter.computeSint32Size(tagNumber, val);
197 }
198 return size;
199 case Builder._REPEATED_SINT64:
200 List<int> list = fieldValue;
201 for (int val in list) {
202 size += CodedBufferWriter.computeSint64Size(tagNumber, val);
203 }
204 return size;
205 case Builder._REPEATED_UINT32:
206 List<int> list = fieldValue;
207 for (int val in list) {
208 size += CodedBufferWriter.computeUint32Size(tagNumber, val);
209 }
210 return size;
211 case Builder._REPEATED_UINT64:
212 List<int> list = fieldValue;
213 for (int val in list) {
214 size += CodedBufferWriter.computeUint64Size(tagNumber, val);
215 }
216 return size;
217 case Builder._REPEATED_FIXED32:
218 List<int> list = fieldValue;
219 for (int val in list) {
220 size += CodedBufferWriter.computeFixed32Size(tagNumber, val);
221 }
222 return size;
223 case Builder._REPEATED_FIXED64:
224 List<int> list = fieldValue;
225 for (int val in list) {
226 size += CodedBufferWriter.computeFixed64Size(tagNumber, val);
227 }
228 return size;
229 case Builder._REPEATED_SFIXED32:
230 List<int> list = fieldValue;
231 for (int val in list) {
232 size += CodedBufferWriter.computeSfixed32Size(tagNumber, val);
233 }
234 return size;
235 case Builder._REPEATED_SFIXED64:
236 List<int> list = fieldValue;
237 for (int val in list) {
238 size += CodedBufferWriter.computeSfixed64Size(tagNumber, val);
239 }
240 return size;
241 case Builder._REPEATED_MESSAGE:
242 for (Message val in fieldValue) {
243 size += CodedBufferWriter.computeMessageSize(tagNumber, val);
244 }
245 return size;
246 case Builder._PACKED_BOOL:
247 return _computePackedSize(tagNumber, fieldValue,
248 CodedBufferWriter.computeBoolSizeNoTag);
249 case Builder._PACKED_FLOAT:
250 return _computePackedSize(tagNumber, fieldValue,
251 CodedBufferWriter.computeFloatSizeNoTag);
252 case Builder._PACKED_DOUBLE:
253 return _computePackedSize(tagNumber, fieldValue,
254 CodedBufferWriter.computeDoubleSizeNoTag);
255 case Builder._PACKED_ENUM:
256 return _computePackedSize(tagNumber, fieldValue,
257 CodedBufferWriter.computeEnumSizeNoTag);
258 case Builder._PACKED_INT32:
259 return _computePackedSize(tagNumber, fieldValue,
260 CodedBufferWriter.computeInt32SizeNoTag);
261 case Builder._PACKED_INT64:
262 return _computePackedSize(tagNumber, fieldValue,
263 CodedBufferWriter.computeInt64SizeNoTag);
264 case Builder._PACKED_UINT32:
265 return _computePackedSize(tagNumber, fieldValue,
266 CodedBufferWriter.computeUint32SizeNoTag);
267 case Builder._PACKED_UINT64:
268 return _computePackedSize(tagNumber, fieldValue,
269 CodedBufferWriter.computeUint64SizeNoTag);
270 case Builder._PACKED_SINT32:
271 return _computePackedSize(tagNumber, fieldValue,
272 CodedBufferWriter.computeSint32SizeNoTag);
273 case Builder._PACKED_SINT64:
274 return _computePackedSize(tagNumber, fieldValue,
275 CodedBufferWriter.computeSint64SizeNoTag);
276 case Builder._PACKED_FIXED32:
277 return _computePackedSize(tagNumber, fieldValue,
278 CodedBufferWriter.computeFixed32SizeNoTag);
279 case Builder._PACKED_FIXED64:
280 return _computePackedSize(tagNumber, fieldValue,
281 CodedBufferWriter.computeFixed64SizeNoTag);
282 case Builder._PACKED_SFIXED32:
283 return _computePackedSize(tagNumber, fieldValue,
284 CodedBufferWriter.computeSfixed32SizeNoTag);
285 case Builder._PACKED_SFIXED64:
286 return _computePackedSize(tagNumber, fieldValue,
287 CodedBufferWriter.computeSfixed64SizeNoTag);
288 default:
289 throw "Unknown type $fieldType";
290 }
291 }
292
293 int _computePackedSize(int tagNumber, List values, var sizeFunc) {
294 int dataSize = 0;
295 for (var val in values) {
296 dataSize += sizeFunc(val);
297 }
298 _serializedSize[tagNumber] = dataSize;
299 if (!values.isEmpty()) {
300 dataSize += CodedBufferWriter.computeInt32Size(tagNumber, dataSize);
301 }
302 return dataSize;
303 }
304
305 int getTagNumber(String fieldName) => _builderInfo.tagNumber(fieldName);
306
307 UnknownFieldSet get unknownFields() => _unknownFields;
308
309 bool hasField(int tagNumber) => _fieldValues.containsKey(tagNumber);
310
311 // Shorthand for hasField
312 bool h_(int tagNumber) => hasField(tagNumber);
313
314 bool hasRequiredFields() => _builderInfo.hasRequiredFields;
315
316 int hashCode() {
317 if (_memoizedHashCode == -1) {
318 _memoizedHashCode = 0;
319 for (int tagNumber in _fieldValues.getKeys()) {
320 _memoizedHashCode = (17 * _memoizedHashCode) + tagNumber;
321 var value = _fieldValues[tagNumber];
322 if (value is Hashable) {
323 _memoizedHashCode = (31 * _memoizedHashCode) + value.hashCode();
324 }
325 }
326 if (_unknownFields != null) {
327 _memoizedHashCode =
328 (23 * _memoizedHashCode) + _unknownFields.hashCode();
329 }
330 }
331 return _memoizedHashCode;
332 }
333
334 void _findInvalidFields(List<String> invalidFields, String prefix) {
335 _builderInfo._findInvalidFields(_fieldValues, invalidFields, prefix);
336 }
337
338 bool isInitialized() {
339 if (!hasRequiredFields()) {
340 return true;
341 }
342 if (_memoizedIsInitialized != -1) {
343 return _memoizedIsInitialized == 1;
344 }
345
346 bool initialized = _builderInfo.isInitialized(_fieldValues);
347 _memoizedIsInitialized = initialized ? 1 : 0;
348 return initialized;
349 }
350
351 String toString() {
352 return _toString();
353 }
354
355 String _toString([String indent = ""]) {
356 StringBuffer s = new StringBuffer();
357 void renderValue(key, value) {
358 if (value is Message) {
359 s.add("${indent}${key}: {\n");
360 s.add(value._toString("$indent "));
361 s.add("${indent}}\n");
362 } else {
363 s.add("${indent}${key}: ${value}\n");
364 }
365 }
366
367 // Sort output by tag number
368 List<FieldInfo> fields = new List<FieldInfo>.from(_builderInfo.fieldInfo.get Values());
369 fields.sort((a, b) => a.tagNumber.compareTo(b.tagNumber));
370 List<String> keys = fields.map((FieldInfo field) => field.name);
371
372 for (FieldInfo field in fields) {
373 if (hasField(field.tagNumber)) {
374 var fieldValue = _fieldValues[field.tagNumber];
375 if (fieldValue is List) {
376 // work around http://code.google.com/p/dart/issues/detail?id=3817
377 for (int i = 0; i < fieldValue.length; i++) {
378 renderValue(field.name, fieldValue[i]);
379 }
380 } else {
381 renderValue(field.name, fieldValue);
382 }
383 }
384 }
385 if (_unknownFields != null) {
386 s.add(_unknownFields.toString());
387 }
388 return s.toString();
389 }
390
391 List<int> writeToBuffer() {
392 CodedBufferWriter out = new CodedBufferWriter(getSerializedSize());
393 writeToCodedBufferWriter(out);
394 return out.buffer;
395 }
396
397 void writeToCodedBufferWriter(CodedBufferWriter output) {
398 getSerializedSize();
399
400 List<int> keys = new List<int>.from(_fieldValues.getKeys());
401 keys.sort((a, b) => a.compareTo(b));
402 for (int tagNumber in keys) {
403 var fieldValue = _fieldValues[tagNumber];
404 int fieldType = _getFieldType(tagNumber) & ~Builder._REQUIRED_BIT;
405 _writeField(output, tagNumber, fieldType, fieldValue);
406 }
407 unknownFields.writeToCodedBufferWriter(output);
408 }
409
410 void _writeField(CodedBufferWriter output, int tagNumber, int fieldType,
411 var fieldValue) {
412 switch (fieldType) {
413 case Builder._OPTIONAL_BOOL:
414 output.writeBool(tagNumber, fieldValue);
415 break;
416 case Builder._OPTIONAL_BYTES:
417 output.writeBytes(tagNumber, fieldValue);
418 break;
419 case Builder._OPTIONAL_STRING:
420 output.writeString(tagNumber, fieldValue);
421 break;
422 case Builder._OPTIONAL_FLOAT:
423 output.writeFloat(tagNumber, fieldValue);
424 break;
425 case Builder._OPTIONAL_DOUBLE:
426 output.writeDouble(tagNumber, fieldValue);
427 break;
428 case Builder._OPTIONAL_ENUM:
429 output.writeEnum(tagNumber, fieldValue);
430 break;
431 case Builder._OPTIONAL_GROUP:
432 output.writeGroup(tagNumber, fieldValue);
433 break;
434 case Builder._OPTIONAL_INT32:
435 output.writeInt32(tagNumber, fieldValue);
436 break;
437 case Builder._OPTIONAL_INT64:
438 output.writeInt64(tagNumber, fieldValue);
439 break;
440 case Builder._OPTIONAL_SINT32:
441 output.writeSint32(tagNumber, fieldValue);
442 break;
443 case Builder._OPTIONAL_SINT64:
444 output.writeSint64(tagNumber, fieldValue);
445 break;
446 case Builder._OPTIONAL_UINT32:
447 output.writeUint32(tagNumber, fieldValue);
448 break;
449 case Builder._OPTIONAL_UINT64:
450 output.writeUint64(tagNumber, fieldValue);
451 break;
452 case Builder._OPTIONAL_FIXED32:
453 output.writeFixed32(tagNumber, fieldValue);
454 break;
455 case Builder._OPTIONAL_FIXED64:
456 output.writeFixed64(tagNumber, fieldValue);
457 break;
458 case Builder._OPTIONAL_SFIXED32:
459 output.writeSfixed32(tagNumber, fieldValue);
460 break;
461 case Builder._OPTIONAL_SFIXED64:
462 output.writeSfixed64(tagNumber, fieldValue);
463 break;
464 case Builder._OPTIONAL_MESSAGE:
465 output.writeMessage(tagNumber, fieldValue);
466 break;
467 case Builder._REPEATED_BOOL:
468 for (bool val in fieldValue) {
469 output.writeBool(tagNumber, val);
470 }
471 break;
472 case Builder._REPEATED_BYTES:
473 for (List<int> val in fieldValue) {
474 output.writeBytes(tagNumber, val);
475 }
476 break;
477 case Builder._REPEATED_STRING:
478 for (String val in fieldValue) {
479 output.writeString(tagNumber, val);
480 }
481 break;
482 case Builder._REPEATED_FLOAT:
483 for (double val in fieldValue) {
484 output.writeFloat(tagNumber, val);
485 }
486 break;
487 case Builder._REPEATED_DOUBLE:
488 for (double val in fieldValue) {
489 output.writeDouble(tagNumber, val);
490 }
491 break;
492 case Builder._REPEATED_ENUM:
493 for (var val in fieldValue) {
494 output.writeEnum(tagNumber, val);
495 }
496 break;
497 case Builder._REPEATED_GROUP:
498 for (var val in fieldValue) {
499 output.writeGroup(tagNumber, val);
500 }
501 break;
502 case Builder._REPEATED_INT32:
503 for (int val in fieldValue) {
504 output.writeInt32(tagNumber, val);
505 }
506 break;
507 case Builder._REPEATED_INT64:
508 for (int val in fieldValue) {
509 output.writeInt64(tagNumber, val);
510 }
511 break;
512 case Builder._REPEATED_SINT32:
513 for (int val in fieldValue) {
514 output.writeSint32(tagNumber, val);
515 }
516 break;
517 case Builder._REPEATED_SINT64:
518 for (int val in fieldValue) {
519 output.writeSint64(tagNumber, val);
520 }
521 break;
522 case Builder._REPEATED_UINT32:
523 for (int val in fieldValue) {
524 output.writeUint32(tagNumber, val);
525 }
526 break;
527 case Builder._REPEATED_UINT64:
528 for (int val in fieldValue) {
529 output.writeUint64(tagNumber, val);
530 }
531 break;
532 case Builder._REPEATED_FIXED32:
533 for (int val in fieldValue) {
534 output.writeFixed32(tagNumber, val);
535 }
536 break;
537 case Builder._REPEATED_FIXED64:
538 for (int val in fieldValue) {
539 output.writeFixed64(tagNumber, val);
540 }
541 break;
542 case Builder._REPEATED_SFIXED32:
543 for (int val in fieldValue) {
544 output.writeSfixed32(tagNumber, val);
545 }
546 break;
547 case Builder._REPEATED_SFIXED64:
548 for (int val in fieldValue) {
549 output.writeSfixed64(tagNumber, val);
550 }
551 break;
552 case Builder._REPEATED_MESSAGE:
553 for (Message val in fieldValue) {
554 output.writeMessage(tagNumber, val);
555 }
556 break;
557 case Builder._PACKED_BOOL:
558 _writePacked(output, tagNumber, fieldValue,
559 output.writeBoolNoTag);
560 break;
561 case Builder._PACKED_FLOAT:
562 _writePacked(output, tagNumber, fieldValue,
563 output.writeFloatNoTag);
564 break;
565 case Builder._PACKED_DOUBLE:
566 _writePacked(output, tagNumber, fieldValue,
567 output.writeDoubleNoTag);
568 break;
569 case Builder._PACKED_ENUM:
570 _writePacked(output, tagNumber, fieldValue,
571 output.writeEnumNoTag);
572 break;
573 case Builder._PACKED_INT32:
574 _writePacked(output, tagNumber, fieldValue,
575 output.writeInt32NoTag);
576 break;
577 case Builder._PACKED_INT64:
578 _writePacked(output, tagNumber, fieldValue,
579 output.writeInt64NoTag);
580 break;
581 case Builder._PACKED_UINT32:
582 _writePacked(output, tagNumber, fieldValue,
583 output.writeUint32NoTag);
584 break;
585 case Builder._PACKED_UINT64:
586 _writePacked(output, tagNumber, fieldValue,
587 output.writeUint64NoTag);
588 break;
589 case Builder._PACKED_SINT32:
590 _writePacked(output, tagNumber, fieldValue,
591 output.writeSint32NoTag);
592 break;
593 case Builder._PACKED_SINT64:
594 _writePacked(output, tagNumber, fieldValue,
595 output.writeSint64NoTag);
596 break;
597 case Builder._PACKED_FIXED32:
598 _writePacked(output, tagNumber, fieldValue,
599 output.writeFixed32NoTag);
600 break;
601 case Builder._PACKED_FIXED64:
602 _writePacked(output, tagNumber, fieldValue,
603 output.writeFixed64NoTag);
604 break;
605 case Builder._PACKED_SFIXED32:
606 _writePacked(output, tagNumber, fieldValue,
607 output.writeSfixed32NoTag);
608 break;
609 case Builder._PACKED_SFIXED64:
610 _writePacked(output, tagNumber, fieldValue,
611 output.writeSfixed64NoTag);
612 break;
613 default:
614 throw "Unknown type $fieldType";
615 }
616 }
617
618 void _writePacked(CodedBufferWriter output, int tagNumber, List values,
619 var writeFunc) {
620 if (values.length > 0) {
621 output.writeTag(tagNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
622 output.writeInt32NoTag(_serializedSize[tagNumber]);
623 }
624 for (var val in values) {
625 writeFunc(val);
626 }
627 }
628
629 /**
630 * Return [:true:] if the given extension field contains data. Returns
631 * [:false:] for a repeated field with no elements.
632 */
633 bool hasExtension(Extension extension) {
634 return hasField(extension.tagNumber);
635 }
636
637 /**
638 * Returns the value of the given extension. For repeated fields that have
639 * not been set previously, [:null:] is returned.
640 */
641 Dynamic getExtension(Extension extension) {
642 var value = _fieldValues[extension.tagNumber];
643 // Initialize the field
644 if (value === null) {
645 var defaultFunc = extension.makeDefault;
646 if (defaultFunc != null) {
647 value = defaultFunc();
648 }
649 if (value != null) {
650 _fieldValues[extension.tagNumber] = value;
651 }
652 }
653 return value;
654 }
655
656 int getExtensionCount(Extension extension) {
657 List list = _fieldValues[extension.tagNumber];
658 return list === null ? 0 : list.length;
659 }
660
661 // JSON support
662
663 // Append a JSON value to a StringBuffer
664 void _writeJsonValue(var fieldValue, int fieldType, StringBuffer sb) {
665 fieldType &= ~(Builder._REPEATED_BIT | Builder._PACKED_BIT);
666 switch (fieldType) {
667 case Builder._BOOL_BIT:
668 sb.add(fieldValue == true ? "true" : "false");
669 break;
670 case Builder._BYTES_BIT:
671 // Encode 'bytes' as a base64-encoded string
672 sb.add('"');
673 sb.add(Base64Codec.defaultInstance.encodeList(fieldValue));
674 sb.add('"');
675 break;
676 case Builder._STRING_BIT:
677 // Perform string escaping
678 sb.add('"');
679 sb.add(PbCodec.escapeString(fieldValue));
680 sb.add('"');
681 break;
682 case Builder._FLOAT_BIT:
683 case Builder._DOUBLE_BIT:
684 // Force 'xxx.0' output for integral values
685 if (fieldValue.floor() == fieldValue) {
686 sb.add(fieldValue.floor().toInt());
687 sb.add('.0');
688 } else {
689 sb.add(fieldValue);
690 }
691 break;
692 case Builder._ENUM_BIT:
693 ProtobufEnum enum = fieldValue;
694 sb.add(enum.value); // assume |value| < 2^52
695 break;
696 case Builder._INT32_BIT:
697 case Builder._SINT32_BIT:
698 case Builder._UINT32_BIT:
699 case Builder._FIXED32_BIT:
700 case Builder._SFIXED32_BIT:
701 sb.add(fieldValue);
702 break;
703 case Builder._INT64_BIT:
704 case Builder._SINT64_BIT:
705 case Builder._UINT64_BIT:
706 case Builder._FIXED64_BIT:
707 case Builder._SFIXED64_BIT:
708 sb.add('"$fieldValue"');
709 break;
710 case Builder._GROUP_BIT:
711 case Builder._MESSAGE_BIT:
712 fieldValue._toJson(sb);
713 break;
714 default:
715 throw "Unknown type $fieldType";
716 }
717 }
718
719 // Convert this message to JSON, appending it to a StringBuffer
720 String _toJson(StringBuffer sb) {
721 List<int> keys = new List<int>.from(_fieldValues.getKeys());
722 keys.sort((a, b) => a.compareTo(b));
723 sb.add("{");
724 bool firstTime = true;
725 for (int tagNumber in keys) {
726 if (!firstTime) {
727 sb.add(",");
728 }
729 firstTime = false;
730 String tagName = _builderInfo.fieldName(tagNumber);
731 sb.add('\"$tagNumber\":');
732 var fieldValue = _fieldValues[tagNumber];
733 int fieldType = _getFieldType(tagNumber) & ~Builder._REQUIRED_BIT;
734 if ((fieldType & Builder._REPEATED_BIT) != 0) {
735 // Encoded repeated values as an array
736 sb.add("[");
737 bool ft = true;
738 for (var value in fieldValue) {
739 if (!ft) {
740 sb.add(",");
741 }
742 ft = false;
743 _writeJsonValue(value, fieldType, sb);
744 }
745 sb.add("]");
746 } else {
747 _writeJsonValue(fieldValue, fieldType, sb);
748 }
749 }
750 sb.add("}");
751 }
752
753 /**
754 * Return a JSON string that encodes this message. Each message (top level
755 * or nested) is represented as an object delimited by curly braces. Within
756 * a message, elements are indexed by tag number (surrounded by quotes).
757 * Repeated elements are represented as arrays.
758 *
759 * Boolean values, strings, and floating-point values are represented as
760 * literals. Values with a 32-bit integer datatype are represented as integer
761 * literals; values with a 64-bit integer datatype (regardless of their
762 * actual runtime value) are represented as strings. Enumerated values are
763 * represented as their integer value.
764 */
765 String writeToJson() {
766 StringBuffer sb = new StringBuffer();
767 _toJson(sb);
768 return sb.toString();
769 }
770
771 // Called from generated code
772 static GeneratedMessage parseJson(Builder builder, String input,
773 [ExtensionRegistry extensionRegistry]) {
774 return builder.mergeFromJson(input, extensionRegistry).buildParsed();
775 }
776 }
OLDNEW
« no previous file with comments | « lib/protobuf/runtime/FieldInfo.dart ('k') | lib/protobuf/runtime/ImmutableList.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698