From 29064dab945f34ee226224139e39ee586f1d9f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Wed, 4 May 2022 13:11:09 +0200 Subject: [PATCH] Clear unknown field when setting an extension field with the same tag Synced from internal repo --- .../lib/src/protobuf/extension_field_set.dart | 3 +++ .../lib/src/protobuf/unknown_field_set.dart | 5 ++++ .../extension_unknown_interaction_test.dart | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 protoc_plugin/test/extension_unknown_interaction_test.dart diff --git a/protobuf/lib/src/protobuf/extension_field_set.dart b/protobuf/lib/src/protobuf/extension_field_set.dart index 2497e0361..c3f9e3afe 100644 --- a/protobuf/lib/src/protobuf/extension_field_set.dart +++ b/protobuf/lib/src/protobuf/extension_field_set.dart @@ -132,6 +132,9 @@ class _ExtensionFieldSet { 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 18a348f21..8c1159c35 100644 --- a/protobuf/lib/src/protobuf/unknown_field_set.dart +++ b/protobuf/lib/src/protobuf/unknown_field_set.dart @@ -28,6 +28,11 @@ class UnknownFieldSet { _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 000000000..9acb38928 --- /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); + }); +}