From 1ed72f9181deccbe57b51852a00202eca9171766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Thu, 6 Feb 2025 13:52:40 +0100 Subject: [PATCH 1/9] Add pragmas --- protobuf/lib/src/protobuf/coded_buffer.dart | 55 ++++++++++++++----- .../lib/src/protobuf/coded_buffer_reader.dart | 31 +++++++++++ 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/protobuf/lib/src/protobuf/coded_buffer.dart b/protobuf/lib/src/protobuf/coded_buffer.dart index a102cbb1d..94e0001c6 100644 --- a/protobuf/lib/src/protobuf/coded_buffer.dart +++ b/protobuf/lib/src/protobuf/coded_buffer.dart @@ -130,7 +130,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_BOOL: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readBool())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readBool()); + _readPacked(input, readElem); } else { list.add(input.readBool()); } @@ -146,7 +148,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_FLOAT: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readFloat())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readFloat()); + _readPacked(input, readElem); } else { list.add(input.readFloat()); } @@ -154,7 +158,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_DOUBLE: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readDouble())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readDouble()); + _readPacked(input, readElem); } else { list.add(input.readDouble()); } @@ -173,7 +179,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_INT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readInt32())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readInt32()); + _readPacked(input, readElem); } else { list.add(input.readInt32()); } @@ -181,7 +189,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_INT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readInt64())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readInt64()); + _readPacked(input, readElem); } else { list.add(input.readInt64()); } @@ -189,7 +199,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SINT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readSint32())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readSint32()); + _readPacked(input, readElem); } else { list.add(input.readSint32()); } @@ -197,7 +209,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SINT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readSint64())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readSint64()); + _readPacked(input, readElem); } else { list.add(input.readSint64()); } @@ -205,7 +219,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_UINT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readUint32())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readUint32()); + _readPacked(input, readElem); } else { list.add(input.readUint32()); } @@ -213,7 +229,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_UINT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readUint64())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readUint64()); + _readPacked(input, readElem); } else { list.add(input.readUint64()); } @@ -221,7 +239,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_FIXED32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readFixed32())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readFixed32()); + _readPacked(input, readElem); } else { list.add(input.readFixed32()); } @@ -229,7 +249,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_FIXED64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readFixed64())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readFixed64()); + _readPacked(input, readElem); } else { list.add(input.readFixed64()); } @@ -237,7 +259,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SFIXED32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readSfixed32())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readSfixed32()); + _readPacked(input, readElem); } else { list.add(input.readSfixed32()); } @@ -245,7 +269,9 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SFIXED64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - _readPacked(input, () => list.add(input.readSfixed64())); + @pragma('vm:prefer-inline') + void readElem() => list.add(input.readSfixed64()); + _readPacked(input, readElem); } else { list.add(input.readSfixed64()); } @@ -269,7 +295,8 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, } } -void _readPacked(CodedBufferReader input, void Function() readFunc) { +@pragma('vm:prefer-inline') +void _readPacked(CodedBufferReader input, final void Function() readFunc) { input._withLimit(input.readInt32(), () { while (!input.isAtEnd()) { readFunc(); diff --git a/protobuf/lib/src/protobuf/coded_buffer_reader.dart b/protobuf/lib/src/protobuf/coded_buffer_reader.dart index cc7e3ddf1..80575ca79 100644 --- a/protobuf/lib/src/protobuf/coded_buffer_reader.dart +++ b/protobuf/lib/src/protobuf/coded_buffer_reader.dart @@ -42,14 +42,17 @@ class CodedBufferReader { throw InvalidProtocolBufferException.truncatedMessage(); } + @pragma('vm:prefer-inline') void checkLastTagWas(int value) { if (_lastTag != value) { throw InvalidProtocolBufferException.invalidEndTag(); } } + @pragma('vm:prefer-inline') bool isAtEnd() => _bufferPos >= _currentLimit; + @pragma('vm:prefer-inline') void _withLimit(int byteLimit, Function() callback) { if (byteLimit < 0) { throw ArgumentError( @@ -66,6 +69,7 @@ class CodedBufferReader { _currentLimit = oldLimit; } + @pragma('vm:prefer-inline') void _checkLimit(int increment) { assert(_currentLimit != -1); _bufferPos += increment; @@ -121,28 +125,45 @@ class CodedBufferReader { _currentLimit = oldLimit; } + @pragma('vm:prefer-inline') int readEnum() => readInt32(); + + @pragma('vm:prefer-inline') int readInt32() => _readRawVarint32(true); + + @pragma('vm:prefer-inline') Int64 readInt64() => _readRawVarint64(); + + @pragma('vm:prefer-inline') int readUint32() => _readRawVarint32(false); + + @pragma('vm:prefer-inline') Int64 readUint64() => _readRawVarint64(); + + @pragma('vm:prefer-inline') int readSint32() => _decodeZigZag32(readUint32()); + + @pragma('vm:prefer-inline') Int64 readSint64() => _decodeZigZag64(readUint64()); + @pragma('vm:prefer-inline') int readFixed32() { final pos = _bufferPos; _checkLimit(4); return _byteData.getUint32(pos, Endian.little); } + @pragma('vm:prefer-inline') Int64 readFixed64() => readSfixed64(); + @pragma('vm:prefer-inline') int readSfixed32() { final pos = _bufferPos; _checkLimit(4); return _byteData.getInt32(pos, Endian.little); } + @pragma('vm:prefer-inline') Int64 readSfixed64() { final pos = _bufferPos; _checkLimit(8); @@ -150,15 +171,18 @@ class CodedBufferReader { return Int64.fromBytes(view); } + @pragma('vm:prefer-inline') bool readBool() => _readRawVarint32(true) != 0; /// Read a length-delimited field as bytes. + @pragma('vm:prefer-inline') Uint8List readBytes() => Uint8List.fromList(readBytesAsView()); /// Read a length-delimited field as a view of the [CodedBufferReader]'s /// buffer. When storing the returned value directly (instead of e.g. parsing /// it as a UTF-8 string and copying) use [readBytes] instead to avoid /// holding on to the whole message, or copy the returned view. + @pragma('vm:prefer-inline') Uint8List readBytesAsView() { final length = readInt32(); _checkLimit(length); @@ -166,6 +190,7 @@ class CodedBufferReader { _buffer.buffer, _buffer.offsetInBytes + _bufferPos - length, length); } + @pragma('vm:prefer-inline') String readString() { final length = readInt32(); final stringPos = _bufferPos; @@ -174,18 +199,21 @@ class CodedBufferReader { .convert(_buffer, stringPos, stringPos + length); } + @pragma('vm:prefer-inline') double readFloat() { final pos = _bufferPos; _checkLimit(4); return _byteData.getFloat32(pos, Endian.little); } + @pragma('vm:prefer-inline') double readDouble() { final pos = _bufferPos; _checkLimit(8); return _byteData.getFloat64(pos, Endian.little); } + @pragma('vm:prefer-inline') int readTag() { if (isAtEnd()) { _lastTag = 0; @@ -228,6 +256,7 @@ class CodedBufferReader { } } + @pragma('vm:prefer-inline') static int _decodeZigZag32(int value) { if ((value & 0x1) == 1) { return -(value >> 1) - 1; @@ -236,11 +265,13 @@ class CodedBufferReader { } } + @pragma('vm:prefer-inline') static Int64 _decodeZigZag64(Int64 value) { if ((value & 0x1) == 1) value = -value; return value >> 1; } + @pragma('vm:prefer-inline') int _readRawVarintByte() { _checkLimit(1); return _buffer[_bufferPos - 1]; From 5073a40360d872fe48bc39d8aa5d765396b6409a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 10:12:08 +0100 Subject: [PATCH 2/9] Inline _readPacked manually --- protobuf/lib/src/protobuf/coded_buffer.dart | 113 +++++++++++--------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/protobuf/lib/src/protobuf/coded_buffer.dart b/protobuf/lib/src/protobuf/coded_buffer.dart index 94e0001c6..ca5d26d9f 100644 --- a/protobuf/lib/src/protobuf/coded_buffer.dart +++ b/protobuf/lib/src/protobuf/coded_buffer.dart @@ -130,9 +130,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_BOOL: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readBool()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readBool()); + } + }); } else { list.add(input.readBool()); } @@ -148,9 +150,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_FLOAT: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readFloat()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readFloat()); + } + }); } else { list.add(input.readFloat()); } @@ -158,9 +162,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_DOUBLE: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readDouble()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readDouble()); + } + }); } else { list.add(input.readDouble()); } @@ -179,9 +185,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_INT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readInt32()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readInt32()); + } + }); } else { list.add(input.readInt32()); } @@ -189,9 +197,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_INT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readInt64()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readInt64()); + } + }); } else { list.add(input.readInt64()); } @@ -199,9 +209,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SINT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readSint32()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readSint32()); + } + }); } else { list.add(input.readSint32()); } @@ -209,9 +221,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SINT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readSint64()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readSint64()); + } + }); } else { list.add(input.readSint64()); } @@ -219,9 +233,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_UINT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readUint32()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readUint32()); + } + }); } else { list.add(input.readUint32()); } @@ -229,9 +245,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_UINT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readUint64()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readUint64()); + } + }); } else { list.add(input.readUint64()); } @@ -239,9 +257,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_FIXED32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readFixed32()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readFixed32()); + } + }); } else { list.add(input.readFixed32()); } @@ -249,9 +269,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_FIXED64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readFixed64()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readFixed64()); + } + }); } else { list.add(input.readFixed64()); } @@ -259,9 +281,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SFIXED32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readSfixed32()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readSfixed32()); + } + }); } else { list.add(input.readSfixed32()); } @@ -269,9 +293,11 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_SFIXED64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - @pragma('vm:prefer-inline') - void readElem() => list.add(input.readSfixed64()); - _readPacked(input, readElem); + input._withLimit(input.readInt32(), () { + while (!input.isAtEnd()) { + list.add(input.readSfixed64()); + } + }); } else { list.add(input.readSfixed64()); } @@ -295,15 +321,6 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, } } -@pragma('vm:prefer-inline') -void _readPacked(CodedBufferReader input, final void Function() readFunc) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - readFunc(); - } - }); -} - void _readPackableToListEnum( List list, BuilderInfo meta, From 8c41b3c9ad44a270623f05e8da8dbde4ce0d0d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 10:16:01 +0100 Subject: [PATCH 3/9] More inline pragmas --- protobuf/lib/src/protobuf/field_set.dart | 2 ++ protobuf/lib/src/protobuf/unknown_field_set.dart | 1 + 2 files changed, 3 insertions(+) diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart index 15c36586d..e5c5a2a65 100644 --- a/protobuf/lib/src/protobuf/field_set.dart +++ b/protobuf/lib/src/protobuf/field_set.dart @@ -4,6 +4,7 @@ part of '../../protobuf.dart'; +@pragma('vm:never-inline') void _throwFrozenMessageModificationError(String messageName, [String? methodName]) { if (methodName != null) { @@ -161,6 +162,7 @@ class _FieldSet { _unknownFields?._markReadOnly(); } + @pragma('vm:prefer-inline') void _ensureWritable() { if (_isReadOnly) { _throwFrozenMessageModificationError(_messageName); diff --git a/protobuf/lib/src/protobuf/unknown_field_set.dart b/protobuf/lib/src/protobuf/unknown_field_set.dart index aa4fe6c35..9fa33cb0c 100644 --- a/protobuf/lib/src/protobuf/unknown_field_set.dart +++ b/protobuf/lib/src/protobuf/unknown_field_set.dart @@ -190,6 +190,7 @@ class UnknownFieldSet { _isReadOnly = true; } + @pragma('vm:prefer-inline') void _ensureWritable(String methodName) { if (_isReadOnly) { _throwFrozenMessageModificationError('UnknownFieldSet', methodName); From edfe97a3e22258fb530571ef6ef16ae9ab6f1571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 10:18:23 +0100 Subject: [PATCH 4/9] Remove redundant checkNotNull calls from pre-null-safe days --- protobuf/lib/src/protobuf/coded_buffer.dart | 1 - protobuf/lib/src/protobuf/field_info.dart | 4 ---- protobuf/lib/src/protobuf/field_set.dart | 3 --- protobuf/lib/src/protobuf/generated_message.dart | 4 ---- 4 files changed, 12 deletions(-) diff --git a/protobuf/lib/src/protobuf/coded_buffer.dart b/protobuf/lib/src/protobuf/coded_buffer.dart index a102cbb1d..1bcb864ff 100644 --- a/protobuf/lib/src/protobuf/coded_buffer.dart +++ b/protobuf/lib/src/protobuf/coded_buffer.dart @@ -31,7 +31,6 @@ void _writeToCodedBufferWriter(_FieldSet fs, CodedBufferWriter out) { void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, CodedBufferReader input, ExtensionRegistry registry) { - ArgumentError.checkNotNull(registry); fs._ensureWritable(); while (true) { final tag = input.readTag(); diff --git a/protobuf/lib/src/protobuf/field_info.dart b/protobuf/lib/src/protobuf/field_info.dart index dffce4a1a..fb245c8bf 100644 --- a/protobuf/lib/src/protobuf/field_info.dart +++ b/protobuf/lib/src/protobuf/field_info.dart @@ -132,8 +132,6 @@ class FieldInfo { {this.valueOf, this.enumValues, this.defaultEnumValue, String? protoName}) : makeDefault = (() => PbList(check: check!)), _protoName = protoName { - ArgumentError.checkNotNull(name, 'name'); - ArgumentError.checkNotNull(tagNumber, 'tagNumber'); assert(_isRepeated(type)); assert(check != null); assert(!_isEnum(type) || valueOf != null); @@ -280,8 +278,6 @@ class MapFieldInfo extends FieldInfo?> { defaultOrMaker: () => PbMap(keyFieldType, valueFieldType), defaultEnumValue: defaultEnumValue, protoName: protoName) { - ArgumentError.checkNotNull(name, 'name'); - ArgumentError.checkNotNull(tagNumber, 'tagNumber'); assert(_isMapField(type)); assert(!_isEnum(type) || valueOf != null); } diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart index 15c36586d..ea3dac841 100644 --- a/protobuf/lib/src/protobuf/field_set.dart +++ b/protobuf/lib/src/protobuf/field_set.dart @@ -258,8 +258,6 @@ class _FieldSet { /// Works for both extended and non-extended fields. /// Suitable for public API. void _setField(int tagNumber, Object value) { - ArgumentError.checkNotNull(value, 'value'); - final meta = _meta; final fi = _nonExtensionInfo(meta, tagNumber); if (fi == null) { @@ -284,7 +282,6 @@ class _FieldSet { /// Works for both extended and non-extended fields. /// Suitable for decoders that do their own validation. void _setFieldUnchecked(BuilderInfo meta, FieldInfo fi, value) { - ArgumentError.checkNotNull(fi, 'fi'); assert(!fi.isRepeated); if (fi.index == null) { _ensureExtensions() diff --git a/protobuf/lib/src/protobuf/generated_message.dart b/protobuf/lib/src/protobuf/generated_message.dart index 5a0b51cea..b16387e01 100644 --- a/protobuf/lib/src/protobuf/generated_message.dart +++ b/protobuf/lib/src/protobuf/generated_message.dart @@ -396,7 +396,6 @@ abstract class GeneratedMessage { /// Sets the value of a non-repeated extension field to [value]. void setExtension(Extension extension, Object value) { - ArgumentError.checkNotNull(value, 'value'); if (_isRepeated(extension.type)) { throw ArgumentError(_fieldSet._setFieldFailedMessage( extension, value, 'repeating field (use get + .add())')); @@ -489,7 +488,6 @@ abstract class GeneratedMessage { /// For generated code only. /// @nodoc void $_setFloat(int index, double value) { - ArgumentError.checkNotNull(value, 'value'); if (!_isFloat32(value)) { _fieldSet._$check(index, value); } @@ -503,7 +501,6 @@ abstract class GeneratedMessage { /// For generated code only. /// @nodoc void $_setSignedInt32(int index, int value) { - ArgumentError.checkNotNull(value, 'value'); if (!_isSigned32(value)) { _fieldSet._$check(index, value); } @@ -513,7 +510,6 @@ abstract class GeneratedMessage { /// For generated code only. /// @nodoc void $_setUnsignedInt32(int index, int value) { - ArgumentError.checkNotNull(value, 'value'); if (!_isUnsigned32(value)) { _fieldSet._$check(index, value); } From 69562f68f253848a8c6d88373437d8eb0bded63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 11:06:15 +0100 Subject: [PATCH 5/9] More tweaks --- protobuf/lib/src/protobuf/field_set.dart | 1 - protobuf/lib/src/protobuf/unknown_field_set.dart | 1 - 2 files changed, 2 deletions(-) diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart index ed1f35df1..5d5188052 100644 --- a/protobuf/lib/src/protobuf/field_set.dart +++ b/protobuf/lib/src/protobuf/field_set.dart @@ -162,7 +162,6 @@ class _FieldSet { _unknownFields?._markReadOnly(); } - @pragma('vm:prefer-inline') void _ensureWritable() { if (_isReadOnly) { _throwFrozenMessageModificationError(_messageName); diff --git a/protobuf/lib/src/protobuf/unknown_field_set.dart b/protobuf/lib/src/protobuf/unknown_field_set.dart index 9fa33cb0c..aa4fe6c35 100644 --- a/protobuf/lib/src/protobuf/unknown_field_set.dart +++ b/protobuf/lib/src/protobuf/unknown_field_set.dart @@ -190,7 +190,6 @@ class UnknownFieldSet { _isReadOnly = true; } - @pragma('vm:prefer-inline') void _ensureWritable(String methodName) { if (_isReadOnly) { _throwFrozenMessageModificationError('UnknownFieldSet', methodName); From 899badbe02c478a771129b7c8e996f83ff42262b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 12:00:48 +0100 Subject: [PATCH 6/9] More tweaks, not sure worth it --- protobuf/lib/src/protobuf/coded_buffer.dart | 230 ++++++++++++------ .../lib/src/protobuf/extension_field_set.dart | 1 + protobuf/lib/src/protobuf/pb_list.dart | 6 + 3 files changed, 157 insertions(+), 80 deletions(-) diff --git a/protobuf/lib/src/protobuf/coded_buffer.dart b/protobuf/lib/src/protobuf/coded_buffer.dart index d49e4ee3b..463b22b5b 100644 --- a/protobuf/lib/src/protobuf/coded_buffer.dart +++ b/protobuf/lib/src/protobuf/coded_buffer.dart @@ -129,45 +129,65 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_BOOL: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readBool()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + // No need to check the element as for `bool` fields we only need to + // check that the value is not null, and we know in `add` below that + // the value isn't null (`readBool` doesn't return `null`). + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readBool()); + } + }); + } } else { - list.add(input.readBool()); + list._checkModifiable('add'); + list._addUnchecked(input.readBool()); } break; case PbFieldType._REPEATED_BYTES: final list = fs._ensureRepeatedField(meta, fi); - list.add(input.readBytes()); + list._checkModifiable('add'); + list._addUnchecked(input.readBytes()); break; case PbFieldType._REPEATED_STRING: final list = fs._ensureRepeatedField(meta, fi); - list.add(input.readString()); + list._checkModifiable('add'); + list._addUnchecked(input.readString()); break; case PbFieldType._REPEATED_FLOAT: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readFloat()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readFloat()); + } + }); + } } else { - list.add(input.readFloat()); + list._checkModifiable('add'); + list._addUnchecked(input.readFloat()); } break; case PbFieldType._REPEATED_DOUBLE: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readDouble()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readDouble()); + } + }); + } } else { - list.add(input.readDouble()); + list._checkModifiable('add'); + list._addUnchecked(input.readDouble()); } break; case PbFieldType._REPEATED_ENUM: @@ -184,121 +204,171 @@ void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, case PbFieldType._REPEATED_INT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readInt32()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readInt32()); + } + }); + } } else { - list.add(input.readInt32()); + list._checkModifiable('add'); + list._addUnchecked(input.readInt32()); } break; case PbFieldType._REPEATED_INT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readInt64()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readInt64()); + } + }); + } } else { - list.add(input.readInt64()); + list._checkModifiable('add'); + list._addUnchecked(input.readInt64()); } break; case PbFieldType._REPEATED_SINT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readSint32()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readSint32()); + } + }); + } } else { - list.add(input.readSint32()); + list._checkModifiable('add'); + list._addUnchecked(input.readSint32()); } break; case PbFieldType._REPEATED_SINT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readSint64()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readSint64()); + } + }); + } } else { - list.add(input.readSint64()); + list._checkModifiable('add'); + list._addUnchecked(input.readSint64()); } break; case PbFieldType._REPEATED_UINT32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readUint32()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readUint32()); + } + }); + } } else { - list.add(input.readUint32()); + list._checkModifiable('add'); + list._addUnchecked(input.readUint32()); } break; case PbFieldType._REPEATED_UINT64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readUint64()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readUint64()); + } + }); + } } else { - list.add(input.readUint64()); + list._checkModifiable('add'); + list._addUnchecked(input.readUint64()); } break; case PbFieldType._REPEATED_FIXED32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readFixed32()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readFixed32()); + } + }); + } } else { - list.add(input.readFixed32()); + list._checkModifiable('add'); + list._addUnchecked(input.readFixed32()); } break; case PbFieldType._REPEATED_FIXED64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readFixed64()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readFixed64()); + } + }); + } } else { - list.add(input.readFixed64()); + list._checkModifiable('add'); + list._addUnchecked(input.readFixed64()); } break; case PbFieldType._REPEATED_SFIXED32: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readSfixed32()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readSfixed32()); + } + }); + } } else { - list.add(input.readSfixed32()); + list._checkModifiable('add'); + list._addUnchecked(input.readSfixed32()); } break; case PbFieldType._REPEATED_SFIXED64: final list = fs._ensureRepeatedField(meta, fi); if (wireType == WIRETYPE_LENGTH_DELIMITED) { - input._withLimit(input.readInt32(), () { - while (!input.isAtEnd()) { - list.add(input.readSfixed64()); - } - }); + final limit = input.readInt32(); + if (limit != 0) { + list._checkModifiable('add'); + input._withLimit(limit, () { + while (!input.isAtEnd()) { + list._addUnchecked(input.readSfixed64()); + } + }); + } } else { - list.add(input.readSfixed64()); + list._checkModifiable('add'); + list._addUnchecked(input.readSfixed64()); } break; case PbFieldType._REPEATED_MESSAGE: diff --git a/protobuf/lib/src/protobuf/extension_field_set.dart b/protobuf/lib/src/protobuf/extension_field_set.dart index f90bb9096..28582dea6 100644 --- a/protobuf/lib/src/protobuf/extension_field_set.dart +++ b/protobuf/lib/src/protobuf/extension_field_set.dart @@ -66,6 +66,7 @@ class _ExtensionFieldSet { return newList; } + @pragma('vm:prefer-inline') dynamic _getFieldOrNull(Extension extension) => _values[extension.tagNumber]; void _clearFieldAndInfo(Extension fi) { diff --git a/protobuf/lib/src/protobuf/pb_list.dart b/protobuf/lib/src/protobuf/pb_list.dart index 792bfff4e..64b046581 100644 --- a/protobuf/lib/src/protobuf/pb_list.dart +++ b/protobuf/lib/src/protobuf/pb_list.dart @@ -52,6 +52,12 @@ class PbList extends ListBase { _wrappedList.add(element); } + @pragma('dart2js:tryInline') + @pragma('vm:prefer-inline') + void _addUnchecked(E element) { + _wrappedList.add(element); + } + @override @pragma('dart2js:never-inline') void addAll(Iterable iterable) { From dc6e8fb395b761f93704bc079d1d99c7649dab2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 13:24:44 +0100 Subject: [PATCH 7/9] Fix warnings --- protobuf/lib/src/protobuf/field_info.dart | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/protobuf/lib/src/protobuf/field_info.dart b/protobuf/lib/src/protobuf/field_info.dart index fb245c8bf..356e7b63c 100644 --- a/protobuf/lib/src/protobuf/field_info.dart +++ b/protobuf/lib/src/protobuf/field_info.dart @@ -131,11 +131,10 @@ class FieldInfo { this.check, this.subBuilder, {this.valueOf, this.enumValues, this.defaultEnumValue, String? protoName}) : makeDefault = (() => PbList(check: check!)), - _protoName = protoName { - assert(_isRepeated(type)); - assert(check != null); - assert(!_isEnum(type) || valueOf != null); - } + _protoName = protoName, + assert(_isRepeated(type)), + assert(check != null), + assert(!_isEnum(type) || valueOf != null); static MakeDefaultFunc? findMakeDefault(int type, dynamic defaultOrMaker) { if (defaultOrMaker == null) return PbFieldType._defaultForType(type); @@ -274,11 +273,11 @@ class MapFieldInfo extends FieldInfo?> { this.valueCreator, {ProtobufEnum? defaultEnumValue, String? protoName}) - : super(name, tagNumber, index, type, + : assert(_isMapField(type)), + super(name, tagNumber, index, type, defaultOrMaker: () => PbMap(keyFieldType, valueFieldType), defaultEnumValue: defaultEnumValue, protoName: protoName) { - assert(_isMapField(type)); assert(!_isEnum(type) || valueOf != null); } From f39ddce0475b0659cb4e66b10e7c40a8222df56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 13:35:30 +0100 Subject: [PATCH 8/9] Fix formatting --- protobuf/lib/src/protobuf/coded_buffer_reader.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/protobuf/lib/src/protobuf/coded_buffer_reader.dart b/protobuf/lib/src/protobuf/coded_buffer_reader.dart index 80575ca79..c4c49ee2c 100644 --- a/protobuf/lib/src/protobuf/coded_buffer_reader.dart +++ b/protobuf/lib/src/protobuf/coded_buffer_reader.dart @@ -127,22 +127,22 @@ class CodedBufferReader { @pragma('vm:prefer-inline') int readEnum() => readInt32(); - + @pragma('vm:prefer-inline') int readInt32() => _readRawVarint32(true); - + @pragma('vm:prefer-inline') Int64 readInt64() => _readRawVarint64(); - + @pragma('vm:prefer-inline') int readUint32() => _readRawVarint32(false); - + @pragma('vm:prefer-inline') Int64 readUint64() => _readRawVarint64(); - + @pragma('vm:prefer-inline') int readSint32() => _decodeZigZag32(readUint32()); - + @pragma('vm:prefer-inline') Int64 readSint64() => _decodeZigZag64(readUint64()); From 23b884d660b03c0bf63c6c80325f5345f3111c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 10 Feb 2025 14:21:13 +0100 Subject: [PATCH 9/9] Make _mergeFromCodedBufferReader parameters final --- protobuf/lib/src/protobuf/coded_buffer.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protobuf/lib/src/protobuf/coded_buffer.dart b/protobuf/lib/src/protobuf/coded_buffer.dart index 463b22b5b..0ef638d50 100644 --- a/protobuf/lib/src/protobuf/coded_buffer.dart +++ b/protobuf/lib/src/protobuf/coded_buffer.dart @@ -29,8 +29,8 @@ void _writeToCodedBufferWriter(_FieldSet fs, CodedBufferWriter out) { } } -void _mergeFromCodedBufferReader(BuilderInfo meta, _FieldSet fs, - CodedBufferReader input, ExtensionRegistry registry) { +void _mergeFromCodedBufferReader(final BuilderInfo meta, final _FieldSet fs, + final CodedBufferReader input, final ExtensionRegistry registry) { fs._ensureWritable(); while (true) { final tag = input.readTag();