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);
+  });
+}