Align the hashCode of a message with an empty unknown field-set with that of no unknown field set (#648)
Port of cl/308005673
diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart
index 45e4d7e..844558c 100644
--- a/protobuf/lib/src/protobuf/field_set.dart
+++ b/protobuf/lib/src/protobuf/field_set.dart
@@ -675,9 +675,7 @@
}
// Hash with unknown fields.
- if (_hasUnknownFields) {
- hash = _HashUtils._combine(hash, _unknownFields.hashCode);
- }
+ hash = _HashUtils._combine(hash, _unknownFields?.hashCode ?? 0);
if (_isReadOnly && _hashCodesCanBeMemoized) {
_frozenState = hash;
diff --git a/protoc_plugin/test/extension_test.dart b/protoc_plugin/test/extension_test.dart
index c4b668a..5925251 100644
--- a/protoc_plugin/test/extension_test.dart
+++ b/protoc_plugin/test/extension_test.dart
@@ -3,6 +3,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:typed_data';
import 'package:protobuf/protobuf.dart';
import 'package:test/test.dart';
@@ -547,4 +548,15 @@
expect(withUnknownFields.stringMap.length, reparsed.stringMap.length);
expect(withUnknownFields.stringMap[0], reparsed.stringMap[0]);
});
+
+ test('consistent hashcode for reparsed messages with extensions', () {
+ final r = ExtensionRegistry()..add(Extend_unittest.outer);
+ final m = TestAllExtensions()
+ ..setExtension(
+ Extend_unittest.outer, Outer()..inner = (Inner()..value = 'hello'));
+ final Uint8List b = m.writeToBuffer();
+ final c = TestAllExtensions.fromBuffer(b);
+ final d = r.reparseMessage(c);
+ expect(m.hashCode, d.hashCode);
+ });
}
diff --git a/protoc_plugin/test/unknown_field_set_test.dart b/protoc_plugin/test/unknown_field_set_test.dart
index e8b36b6..7ca5efd 100755
--- a/protoc_plugin/test/unknown_field_set_test.dart
+++ b/protoc_plugin/test/unknown_field_set_test.dart
@@ -316,4 +316,13 @@
_checkNotEqual(f1, f2);
});
+
+ test(
+ 'consistent hashcode for messages with no unknown fields set and an empty unknown field set',
+ () {
+ final m = TestAllExtensions();
+ // Force an unknown field set.
+ final m2 = TestAllExtensions()..unknownFields;
+ expect(m.hashCode, m2.hashCode);
+ });
}