diff --git a/protobuf/lib/protobuf.dart b/protobuf/lib/protobuf.dart index f68e779a..f2880196 100644 --- a/protobuf/lib/protobuf.dart +++ b/protobuf/lib/protobuf.dart @@ -18,7 +18,5 @@ export 'src/protobuf/internal.dart' GeneratedMessageInternalExtension, MapFieldInfoInternalExtension, checkNotNull, - mapKeyFieldNumber, - mapValueFieldNumber, mergeFromProto3JsonAny, writeToProto3JsonAny; diff --git a/protobuf/lib/src/protobuf/coded_buffer.dart b/protobuf/lib/src/protobuf/coded_buffer.dart index 2a97d51e..ebfe6d7c 100644 --- a/protobuf/lib/src/protobuf/coded_buffer.dart +++ b/protobuf/lib/src/protobuf/coded_buffer.dart @@ -355,15 +355,32 @@ void _mergeFromCodedBufferReader( case PbFieldType.MAP: final mapFieldInfo = fi as MapFieldInfo; final mapEntryMeta = mapFieldInfo.mapEntryBuilderInfo; - fs - ._ensureMapField(meta, mapFieldInfo) - ._mergeEntry(mapEntryMeta, input, registry); + final map = fs._ensureMapField(meta, mapFieldInfo); + _readMapEntry(map, mapEntryMeta, input, registry); default: throw UnsupportedError('Unknown field type $fieldType'); } } } +void _readMapEntry( + PbMap map, + BuilderInfo meta, + CodedBufferReader input, + ExtensionRegistry registry, +) { + final length = input.readInt32(); + final oldLimit = input._currentLimit; + input._currentLimit = input._bufferPos + length; + final entryFieldSet = FieldSet(null, meta); + _mergeFromCodedBufferReader(meta, entryFieldSet, input, registry); + input.checkLastTagWas(0); + input._currentLimit = oldLimit; + final key = entryFieldSet._values[0] ?? meta.byIndex[0].makeDefault!(); + final value = entryFieldSet._values[1] ?? meta.byIndex[1].makeDefault!(); + map[key] = value; +} + void _readPackableToListEnum( List list, BuilderInfo meta, diff --git a/protobuf/lib/src/protobuf/coded_buffer_writer.dart b/protobuf/lib/src/protobuf/coded_buffer_writer.dart index 8d0e198b..387fb2e2 100644 --- a/protobuf/lib/src/protobuf/coded_buffer_writer.dart +++ b/protobuf/lib/src/protobuf/coded_buffer_writer.dart @@ -88,14 +88,9 @@ class CodedBufferWriter { map.forEach((key, value) { _writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); final mark = _startLengthDelimited(); + _writeValue(mapKeyFieldNumber, map.keyFieldType, key, keyWireFormat); _writeValue( - PbMap._keyFieldNumber, - map.keyFieldType, - key, - keyWireFormat, - ); - _writeValue( - PbMap._valueFieldNumber, + mapValueFieldNumber, map.valueFieldType, value, valueWireFormat, diff --git a/protobuf/lib/src/protobuf/extension_field_set.dart b/protobuf/lib/src/protobuf/extension_field_set.dart index fc73fc30..bb954e25 100644 --- a/protobuf/lib/src/protobuf/extension_field_set.dart +++ b/protobuf/lib/src/protobuf/extension_field_set.dart @@ -232,7 +232,7 @@ class ExtensionFieldSet { final fieldInfo = _info[tag]!; if (fieldInfo.isMapField) { final PbMap? map = value; - newValues[tag] = map?._deepCopy(); + newValues[tag] = map?.deepCopy(); } else if (fieldInfo.isRepeated) { final PbList? list = value; newValues[tag] = list?.deepCopy(); diff --git a/protobuf/lib/src/protobuf/field_info.dart b/protobuf/lib/src/protobuf/field_info.dart index dbdd7d0e..cf5b28cc 100644 --- a/protobuf/lib/src/protobuf/field_info.dart +++ b/protobuf/lib/src/protobuf/field_info.dart @@ -311,7 +311,7 @@ class MapFieldInfo extends FieldInfo?> { } FieldInfo get valueFieldInfo => - mapEntryBuilderInfo.fieldInfo[PbMap._valueFieldNumber]!; + mapEntryBuilderInfo.fieldInfo[mapValueFieldNumber]!; PbMap _ensureMapField(BuilderInfo meta, FieldSet fs) { return fs._ensureMapField(meta, this); diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart index eb90a79b..e2f03f9e 100644 --- a/protobuf/lib/src/protobuf/field_set.dart +++ b/protobuf/lib/src/protobuf/field_set.dart @@ -953,7 +953,7 @@ class FieldSet { if (fieldInfo.isMapField) { final PbMap? originalMap = original._values[index]; if (originalMap == null) continue; - _values[index] = originalMap._deepCopy(); + _values[index] = originalMap.deepCopy(); } else if (fieldInfo.isRepeated) { final PbList? originalList = original._values[index]; if (originalList == null) continue; diff --git a/protobuf/lib/src/protobuf/internal.dart b/protobuf/lib/src/protobuf/internal.dart index f8e9eda7..4bfd34b0 100644 --- a/protobuf/lib/src/protobuf/internal.dart +++ b/protobuf/lib/src/protobuf/internal.dart @@ -7,7 +7,6 @@ /// [1]: https://developers.google.com/protocol-buffers library; -import 'dart:collection' show MapBase; import 'dart:convert' show Utf8Decoder, Utf8Encoder, base64Decode, base64Encode; import 'dart:math' as math; import 'dart:typed_data' show ByteData, Endian, Uint8List; @@ -21,11 +20,13 @@ import 'json/json.dart' as json_lib; import 'json_parsing_context.dart'; import 'mixins/well_known.dart'; import 'pb_list.dart'; +import 'pb_map.dart'; import 'permissive_compare.dart'; import 'type_registry.dart'; import 'utils.dart'; export 'pb_list.dart' show PbList; +export 'pb_map.dart' show PbMap; export 'type_registry.dart' show TypeRegistry; part 'annotations.dart'; @@ -44,7 +45,6 @@ part 'field_type.dart'; part 'generated_message.dart'; part 'generated_service.dart'; part 'message_set.dart'; -part 'pb_map.dart'; part 'proto3_json.dart'; part 'protobuf_enum.dart'; part 'rpc_client.dart'; diff --git a/protobuf/lib/src/protobuf/json/json.dart b/protobuf/lib/src/protobuf/json/json.dart index 05d1ac11..84c87193 100644 --- a/protobuf/lib/src/protobuf/json/json.dart +++ b/protobuf/lib/src/protobuf/json/json.dart @@ -8,6 +8,7 @@ import 'package:fixnum/fixnum.dart' show Int64; import '../consts.dart'; import '../internal.dart'; +import '../pb_map.dart'; import '../utils.dart'; // Use json_vm.dart with VM and dart2wasm, json_web.dart with dart2js. diff --git a/protobuf/lib/src/protobuf/json/json_web.dart b/protobuf/lib/src/protobuf/json/json_web.dart index 84d6482f..1912ffd4 100644 --- a/protobuf/lib/src/protobuf/json/json_web.dart +++ b/protobuf/lib/src/protobuf/json/json_web.dart @@ -10,6 +10,7 @@ import 'package:fixnum/fixnum.dart' show Int64; import '../consts.dart'; import '../internal.dart'; +import '../pb_map.dart'; import '../utils.dart'; @JS('JSON') diff --git a/protobuf/lib/src/protobuf/pb_map.dart b/protobuf/lib/src/protobuf/pb_map.dart index 0f45c2cf..00513337 100644 --- a/protobuf/lib/src/protobuf/pb_map.dart +++ b/protobuf/lib/src/protobuf/pb_map.dart @@ -2,7 +2,10 @@ // 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. -part of 'internal.dart'; +import 'dart:collection' show MapBase; + +import 'internal.dart'; +import 'utils.dart'; const mapKeyFieldNumber = 1; const mapValueFieldNumber = 2; @@ -21,9 +24,6 @@ class PbMap extends MapBase { /// The `int` value is interpreted the same way as [FieldInfo.type]. final int valueFieldType; - static const int _keyFieldNumber = 1; - static const int _valueFieldNumber = 2; - /// The actual list storing the elements. /// /// Note: We want only one [Map] implementation class to be stored here to @@ -103,25 +103,6 @@ class PbMap extends MapBase { return _wrappedMap.remove(key); } - void _mergeEntry( - BuilderInfo mapEntryMeta, - CodedBufferReader input, - ExtensionRegistry registry, - ) { - final length = input.readInt32(); - final oldLimit = input._currentLimit; - input._currentLimit = input._bufferPos + length; - final entryFieldSet = FieldSet(null, mapEntryMeta); - _mergeFromCodedBufferReader(mapEntryMeta, entryFieldSet, input, registry); - input.checkLastTagWas(0); - input._currentLimit = oldLimit; - final key = - entryFieldSet._values[0] ?? mapEntryMeta.byIndex[0].makeDefault!(); - final value = - entryFieldSet._values[1] ?? mapEntryMeta.byIndex[1].makeDefault!(); - _wrappedMap[key] = value; - } - PbMap freeze() { _isReadOnly = true; if (PbFieldType.isGroupOrMessage(valueFieldType)) { @@ -147,3 +128,10 @@ class PbMap extends MapBase { return newMap; } } + +extension PbMapInternalExtension on PbMap { + @pragma('dart2js:tryInline') + @pragma('vm:prefer-inline') + @pragma('wasm:prefer-inline') + PbMap deepCopy() => _deepCopy(); +}