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

Side by Side Diff: lib/generated_message.dart

Issue 64753003: Update hashCode to hash the entire message (Closed) Base URL: https://github.com/dart-lang/dart-protobuf.git@master
Patch Set: Update version number Created 7 years, 1 month 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
« no previous file with comments | « no previous file | lib/pb_list.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of protobuf; 5 part of protobuf;
6 6
7 typedef GeneratedMessage CreateBuilderFunc(); 7 typedef GeneratedMessage CreateBuilderFunc();
8 typedef Object MakeDefaultFunc(); 8 typedef Object MakeDefaultFunc();
9 typedef ProtobufEnum ValueOfFunc(int value); 9 typedef ProtobufEnum ValueOfFunc(int value);
10 10
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 if (other is! GeneratedMessage) return false; 272 if (other is! GeneratedMessage) return false;
273 273
274 GeneratedMessage o = other; 274 GeneratedMessage o = other;
275 if (o.info_ != info_) return false; 275 if (o.info_ != info_) return false;
276 if (!_areMapsEqual(o._fieldValues, _fieldValues)) return false; 276 if (!_areMapsEqual(o._fieldValues, _fieldValues)) return false;
277 if (o.unknownFields != unknownFields) return false; 277 if (o.unknownFields != unknownFields) return false;
278 278
279 return true; 279 return true;
280 } 280 }
281 281
282 int get hashCode => _fieldValues.hashCode; 282 int get hashCode {
283 int hash;
284
285 void hashEnumList(PbList enums) {
286 enums.forEach((enum) {
287 hash = (31 * hash + enum.value) & 0x3fffffff;
288 });
289 }
290
291 void hashFields() {
292 for (int tagNumber in sorted(_fieldValues.keys)) {
293 if (!hasField(tagNumber)) continue;
294 var value = _fieldValues[tagNumber];
295 hash = ((37 * hash) + tagNumber) & 0x3fffffff;
296 int fieldType = _getFieldType(tagNumber);
297 if (_toBaseFieldType(fieldType) != _ENUM_BIT) {
298 hash = ((53 * hash) + value.hashCode) & 0x3fffffff;
299 } else if ((fieldType & _REPEATED_BIT) != 0) {
300 hashEnumList(value);
301 } else {
302 hash = ((53 * hash) + value.value) & 0x3fffffff;
303 }
304 }
305 }
306
307 // Generate hash.
308 hash = 41;
309 // Hash with descriptor.
310 hash = ((19 * hash) + info_.hashCode) & 0x3fffffff;
311 // Hash with fields.
312 hashFields();
313 // Hash with unknown fields.
314 hash = ((29 * hash) + unknownFields.hashCode) & 0x3fffffff;
315 return hash;
316 }
283 317
284 String toString() => _toString(''); 318 String toString() => _toString('');
285 319
286 String _toString(String indent) { 320 String _toString(String indent) {
287 StringBuffer s = new StringBuffer(); 321 StringBuffer s = new StringBuffer();
288 void renderValue(key, value) { 322 void renderValue(key, value) {
289 if (value is GeneratedMessage) { 323 if (value is GeneratedMessage) {
290 s.write('${indent}${key}: {\n'); 324 s.write('${indent}${key}: {\n');
291 s.write(value._toString('$indent ')); 325 s.write(value._toString('$indent '));
292 s.write('${indent}}\n'); 326 s.write('${indent}}\n');
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 iocReadFunc(list.add); 399 iocReadFunc(list.add);
366 } 400 }
367 } 401 }
368 402
369 void readPackable(int wireType, int tagNumber, var readFunc) { 403 void readPackable(int wireType, int tagNumber, var readFunc) {
370 readPackableIoc(wireType, tagNumber, 404 readPackableIoc(wireType, tagNumber,
371 (var assigner) => assigner(readFunc())); 405 (var assigner) => assigner(readFunc()));
372 } 406 }
373 407
374 bool wireTypeMatch(int tagNumber, int fieldType, int wireType) { 408 bool wireTypeMatch(int tagNumber, int fieldType, int wireType) {
375 int fieldDataType = fieldType & 409 switch (_toBaseFieldType(fieldType)) {
376 ~(_REQUIRED_BIT | _REPEATED_BIT | _PACKED_BIT);
377 switch (fieldDataType) {
378 case _BOOL_BIT: 410 case _BOOL_BIT:
379 case _ENUM_BIT: 411 case _ENUM_BIT:
380 case _INT32_BIT: 412 case _INT32_BIT:
381 case _INT64_BIT: 413 case _INT64_BIT:
382 case _SINT32_BIT: 414 case _SINT32_BIT:
383 case _SINT64_BIT: 415 case _SINT64_BIT:
384 case _UINT32_BIT: 416 case _UINT32_BIT:
385 case _UINT64_BIT: 417 case _UINT64_BIT:
386 return wireType == WIRETYPE_VARINT || 418 return wireType == WIRETYPE_VARINT ||
387 wireType == WIRETYPE_LENGTH_DELIMITED; 419 wireType == WIRETYPE_LENGTH_DELIMITED;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 * represented as their integer value. 696 * represented as their integer value.
665 */ 697 */
666 String writeToJson() => JSON.encode(_toMap()); 698 String writeToJson() => JSON.encode(_toMap());
667 699
668 // Merge fields from a previously decoded JSON object. 700 // Merge fields from a previously decoded JSON object.
669 GeneratedMessage _mergeFromJson( 701 GeneratedMessage _mergeFromJson(
670 Map<String, dynamic> json, 702 Map<String, dynamic> json,
671 ExtensionRegistry extensionRegistry) { 703 ExtensionRegistry extensionRegistry) {
672 // Extract a value from its JSON representation. 704 // Extract a value from its JSON representation.
673 convertJsonValue(var value, int tagNumber, int fieldType) { 705 convertJsonValue(var value, int tagNumber, int fieldType) {
674 // Mask off 'required', 'repeated' and 'packed' bits to obtain base type.
675 fieldType &= ~(_REQUIRED_BIT | _REPEATED_BIT | _PACKED_BIT);
676
677 String expectedType; // for exception message 706 String expectedType; // for exception message
678 switch (fieldType) { 707 switch (_toBaseFieldType(fieldType)) {
679 case _BOOL_BIT: 708 case _BOOL_BIT:
680 if (value is bool) { 709 if (value is bool) {
681 return value; 710 return value;
682 } else if (value is String) { 711 } else if (value is String) {
683 if (value == 'true') { 712 if (value == 'true') {
684 return true; 713 return true;
685 } else if (value == 'false') { 714 } else if (value == 'false') {
686 return false; 715 return false;
687 } 716 }
688 } 717 }
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 * or from a known extension. If the type is unknown, [null] is returned. 1019 * or from a known extension. If the type is unknown, [null] is returned.
991 */ 1020 */
992 int _getFieldType(int tagNumber) { 1021 int _getFieldType(int tagNumber) {
993 int type = info_.fieldType(tagNumber); 1022 int type = info_.fieldType(tagNumber);
994 if (type == null && _extensions.containsKey(tagNumber)) { 1023 if (type == null && _extensions.containsKey(tagNumber)) {
995 type = _extensions[tagNumber].type; 1024 type = _extensions[tagNumber].type;
996 } 1025 }
997 return type; 1026 return type;
998 } 1027 }
999 1028
1029 /**
1030 * Returns the type associated with a given tag number, either from the
1031 * [BuilderInfo] associated with this [GeneratedMessage],
1032 * or from a known extension. If the type is unknown, [null] is returned.
1033 */
1034 int _getBaseFieldType(int tagNumber) {
1035 int type = info_.fieldType(tagNumber);
1036 if (type == null && _extensions.containsKey(tagNumber)) {
1037 type = _extensions[tagNumber].type;
1038 }
1039 return type;
1040 }
1041
1042 /*
1043 * Returns the base field type without any of the required, repeated
1044 * and packed bits.
1045 */
1046 int _toBaseFieldType(int fieldType) {
1047 return fieldType & ~(_REQUIRED_BIT | _REPEATED_BIT | _PACKED_BIT);
1048 }
1049
1000 GeneratedMessage _getEmptyMessage( 1050 GeneratedMessage _getEmptyMessage(
1001 int tagNumber, ExtensionRegistry extensionRegistry) { 1051 int tagNumber, ExtensionRegistry extensionRegistry) {
1002 CreateBuilderFunc subBuilderFunc = info_.subBuilder(tagNumber); 1052 CreateBuilderFunc subBuilderFunc = info_.subBuilder(tagNumber);
1003 if (subBuilderFunc == null && extensionRegistry != null) { 1053 if (subBuilderFunc == null && extensionRegistry != null) {
1004 subBuilderFunc = extensionRegistry.getExtension(info_.messageName, 1054 subBuilderFunc = extensionRegistry.getExtension(info_.messageName,
1005 tagNumber).subBuilder; 1055 tagNumber).subBuilder;
1006 } 1056 }
1007 return subBuilderFunc(); 1057 return subBuilderFunc();
1008 } 1058 }
1009 1059
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 _generateMessage(tagNumber, value, 'not a GeneratedMessage')); 1234 _generateMessage(tagNumber, value, 'not a GeneratedMessage'));
1185 } 1235 }
1186 break; 1236 break;
1187 default: 1237 default:
1188 throw new ArgumentError( 1238 throw new ArgumentError(
1189 _generateMessage(tagNumber, value, 'field has unknown type ' 1239 _generateMessage(tagNumber, value, 'field has unknown type '
1190 '$fieldType')); 1240 '$fieldType'));
1191 } 1241 }
1192 } 1242 }
1193 } 1243 }
OLDNEW
« no previous file with comments | « no previous file | lib/pb_list.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698