Clear unknown field when setting an extension field with the same tag (#639)
Synced from internal repo
diff --git a/protobuf/lib/src/protobuf/extension_field_set.dart b/protobuf/lib/src/protobuf/extension_field_set.dart
index 2497e03..c3f9e3a 100644
--- a/protobuf/lib/src/protobuf/extension_field_set.dart
+++ b/protobuf/lib/src/protobuf/extension_field_set.dart
@@ -132,6 +132,9 @@
if (_parent._hasObservers) {
_parent._eventPlugin!.beforeSetField(fi, value);
}
+ // If there was already an unknown field with the same tag number,
+ // overwrite it.
+ _parent._unknownFields?.clearField(fi.tagNumber);
_values[fi.tagNumber] = value;
}
diff --git a/protobuf/lib/src/protobuf/unknown_field_set.dart b/protobuf/lib/src/protobuf/unknown_field_set.dart
index 18a348f..8c1159c 100644
--- a/protobuf/lib/src/protobuf/unknown_field_set.dart
+++ b/protobuf/lib/src/protobuf/unknown_field_set.dart
@@ -28,6 +28,11 @@
_fields.clear();
}
+ void clearField(int tagNumber) {
+ _ensureWritable('clearField');
+ _fields.remove(tagNumber);
+ }
+
UnknownFieldSetField? getField(int tagNumber) => _fields[tagNumber];
bool hasField(int tagNumber) => _fields.containsKey(tagNumber);
diff --git a/protoc_plugin/test/extension_unknown_interaction_test.dart b/protoc_plugin/test/extension_unknown_interaction_test.dart
new file mode 100644
index 0000000..9acb389
--- /dev/null
+++ b/protoc_plugin/test/extension_unknown_interaction_test.dart
@@ -0,0 +1,23 @@
+#!/usr/bin/env dart
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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 'package:protobuf/protobuf.dart';
+import 'package:test/test.dart';
+
+import '../out/protos/google/protobuf/unittest.pb.dart';
+
+void main() {
+ test('setExtension clears unknown field with same tag number', () {
+ final m = TestAllExtensions();
+ m.unknownFields.addField(Unittest.optionalInt32Extension.tagNumber,
+ UnknownFieldSetField()..addFixed32(33));
+ expect(m.unknownFields.hasField(Unittest.optionalInt32Extension.tagNumber),
+ isTrue);
+ m.setExtension(Unittest.optionalInt32Extension, 42);
+ expect(m.getExtension(Unittest.optionalInt32Extension), 42);
+ expect(m.unknownFields.hasField(Unittest.optionalInt32Extension.tagNumber),
+ isFalse);
+ });
+}