Skip to content

Commit

Permalink
Sync changes from internal repo. (google#82)
Browse files Browse the repository at this point in the history
* Added fast getters for common types.
* Only pass index instead of both tag and index to accessors.
* Delegate more methods to underlying list in PbList.

Fixes google#76.
  • Loading branch information
jakobr-google authored Jan 12, 2018
1 parent 34f3347 commit e1d646f
Show file tree
Hide file tree
Showing 11 changed files with 340 additions and 100 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.6.1

* Added fast getters for common types.
* Only pass index instead of both tag and index to accessors.
* Delegate more methods to underlying list in PbList.
* Small fixes for Dart 2.0.

## 0.6.0

* Added enumValues to FieldInfo. Fixes #63.
Expand Down
3 changes: 3 additions & 0 deletions lib/meta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ const List<String> GeneratedMessage_reservedNames = const [
'unknownFields',
'clone',
r'$_get',
r'$_getI64',
r'$_getN',
r'$_getS',
r'$_has',
r'$_setBool',
r'$_setBytes',
Expand Down
2 changes: 1 addition & 1 deletion lib/protobuf.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
library protobuf;

import 'dart:async' show Future;
import 'dart:collection' show ListMixin;
import 'dart:collection' show ListBase;
import 'dart:convert' show BASE64, JSON, Utf8Codec;
import 'dart:math' as math;
import 'dart:typed_data' show TypedData, Uint8List, ByteData, Endianness;
Expand Down
44 changes: 37 additions & 7 deletions lib/src/protobuf/builder_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ part of protobuf;
/// Per-message type setup.
class BuilderInfo {
final String messageName;
final List<FieldInfo> byIndex = <FieldInfo>[];
final Map<int, FieldInfo> fieldInfo = new Map<int, FieldInfo>();
final Map<String, FieldInfo> byTagAsString = <String, FieldInfo>{};
final Map<String, FieldInfo> byName = <String, FieldInfo>{};
Expand All @@ -24,9 +25,9 @@ class BuilderInfo {
CreateBuilderFunc subBuilder,
ValueOfFunc valueOf,
List<ProtobufEnum> enumValues) {
var index = fieldInfo.length;
addField(new FieldInfo<T>(name, tagNumber, index, fieldType, defaultOrMaker,
subBuilder, valueOf, enumValues));
var index = byIndex.length;
_addField(new FieldInfo<T>(name, tagNumber, index, fieldType,
defaultOrMaker, subBuilder, valueOf, enumValues));
}

void addRepeated<T>(
Expand All @@ -37,12 +38,14 @@ class BuilderInfo {
CreateBuilderFunc subBuilder,
ValueOfFunc valueOf,
List<ProtobufEnum> enumValues) {
var index = fieldInfo.length;
addField(new FieldInfo<T>.repeated(name, tagNumber, index, fieldType, check,
subBuilder, valueOf, enumValues));
var index = byIndex.length;
_addField(new FieldInfo<T>.repeated(name, tagNumber, index, fieldType,
check, subBuilder, valueOf, enumValues));
}

void addField(FieldInfo fi) {
void _addField(FieldInfo fi) {
byIndex.add(fi);
assert(byIndex[fi.index] == fi);
fieldInfo[fi.tagNumber] = fi;
byTagAsString["${fi.tagNumber}"] = fi;
byName[fi.name] = fi;
Expand All @@ -57,6 +60,33 @@ class BuilderInfo {
enumValues);
}

/// Adds PbFieldType.OS String with no default value to reduce generated
/// code size.
void aOS(int tagNumber, String name) {
add<String>(tagNumber, name, PbFieldType.OS, null, null, null, null);
}

/// Adds PbFieldType.PS String with no default value.
void pPS(int tagNumber, String name) {
addRepeated<String>(tagNumber, name, PbFieldType.PS,
getCheckFunction(PbFieldType.PS), null, null, null);
}

/// Adds PbFieldType.QS String with no default value.
void aQS(int tagNumber, String name) {
add<String>(tagNumber, name, PbFieldType.QS, null, null, null, null);
}

/// Adds Int64 field with Int64.ZERO default.
void aInt64(int tagNumber, String name) {
add<Int64>(tagNumber, name, PbFieldType.O6, Int64.ZERO, null, null, null);
}

/// Adds a boolean with no default value.
void aOB(int tagNumber, String name) {
add<bool>(tagNumber, name, PbFieldType.OB, null, null, null, null);
}

// Enum.
void e<T>(int tagNumber, String name, int fieldType, dynamic defaultOrMaker,
ValueOfFunc valueOf, List<ProtobufEnum> enumValues) {
Expand Down
78 changes: 57 additions & 21 deletions lib/src/protobuf/field_set.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ class _FieldSet {

_FieldSet(this._message, BuilderInfo meta, this._eventPlugin)
: this._meta = meta,
_values = _makeValueList(meta.fieldInfo);
_values = _makeValueList(meta.byIndex.length);

static _makeValueList(Map<int, FieldInfo> infos) {
if (infos.isEmpty) return const [];
return new List(infos.length);
static _makeValueList(int length) {
if (length == 0) return _zeroList;
return new List(length);
}

// Use a fixed length list and not a constant list to ensure that _values
// always has the same implementation type.
static List _zeroList = new List(0);

// Metadata about multiple fields

String get _messageName => _meta.messageName;
Expand Down Expand Up @@ -69,6 +73,9 @@ class _FieldSet {
/// Returns FieldInfo for a non-extension field, or null if not found.
FieldInfo _nonExtensionInfo(int tagNumber) => _meta.fieldInfo[tagNumber];

/// Returns FieldInfo for a non-extension field.
FieldInfo _nonExtensionInfoByIndex(int index) => _meta.byIndex[index];

/// Returns the FieldInfo for a regular or extension field.
/// throws ArgumentException if no info is found.
FieldInfo _ensureInfo(int tagNumber) {
Expand Down Expand Up @@ -138,7 +145,7 @@ class _FieldSet {

bool _hasField(int tagNumber) {
var fi = _nonExtensionInfo(tagNumber);
if (fi != null) return _$has(fi.index, tagNumber);
if (fi != null) return _$has(fi.index);
if (!_hasExtensions) return false;
return _extensions._hasField(tagNumber);
}
Expand Down Expand Up @@ -235,17 +242,43 @@ class _FieldSet {
// Generated method implementations

/// The implementation of a generated getter.
T _$get<T>(int index, int tagNumber, T defaultValue) {
assert(_nonExtensionInfo(tagNumber).index == index);
T _$get<T>(int index, T defaultValue) {
var value = _values[index];
if (value != null) return value as T;
if (defaultValue != null) return defaultValue;
return _getDefault(_nonExtensionInfo(tagNumber)) as T;
return _getDefault(_nonExtensionInfoByIndex(index)) as T;
}

/// The implementation of a generated getter. Common case for submessages.
T _$getN<T>(int index) {
var value = _values[index];
if (value != null) return value as T;
return _getDefault(_nonExtensionInfoByIndex(index)) as T;
}

/// The implementation of a generated getter for String fields.
String _$getS(int index, String defaultValue) {
var value = _values[index];
if (value == null) {
if (defaultValue != null) return defaultValue;
value = _getDefault(_nonExtensionInfoByIndex(index));
}
String result = value;
return result;
}

/// The implementation of a generated getter for Int64 fields.
Int64 _$getI64(int index) {
var value = _values[index];
if (value == null) {
value = _getDefault(_nonExtensionInfoByIndex(index));
}
Int64 result = value;
return result;
}

/// The implementation of a generated has method.
bool _$has(int index, int tagNumber) {
assert(_nonExtensionInfo(tagNumber).index == index);
/// The implementation of a generated 'has' method.
bool _$has(int index) {
var value = _values[index];
if (value == null) return false;
if (value is List) return value.isNotEmpty;
Expand All @@ -257,25 +290,24 @@ class _FieldSet {
/// In production, does no validation other than a null check.
/// Only handles non-repeated, non-extension fields.
/// Also, doesn't handle enums or messages which need per-type validation.
void _$set(int index, int tagNumber, value) {
assert(_nonExtensionInfo(tagNumber).index == index);
assert(!_nonExtensionInfo(tagNumber).isRepeated);
assert(_$check(tagNumber, value));
void _$set(int index, value) {
assert(!_nonExtensionInfoByIndex(index).isRepeated);
assert(_$check(index, value));
if (_isReadOnly) {
throw new UnsupportedError(
"attempted to call a setter on a read-only message ($_messageName)");
}
if (value == null) {
_$check(tagNumber, value); // throw exception for null value
_$check(index, value); // throw exception for null value
}
if (_hasObservers) {
_eventPlugin.beforeSetField(_nonExtensionInfo(tagNumber), value);
_eventPlugin.beforeSetField(_nonExtensionInfoByIndex(index), value);
}
_values[index] = value;
}

bool _$check(int tagNumber, var newValue) {
_validateField(_nonExtensionInfo(tagNumber), newValue);
bool _$check(int index, var newValue) {
_validateField(_nonExtensionInfoByIndex(index), newValue);
return true; // Allows use in an assertion.
}

Expand Down Expand Up @@ -486,12 +518,16 @@ class _FieldSet {

if (fi.isRepeated) {
if (mustClone) {
// fieldValue must be a PbList of GeneratedMessage.
PbList<GeneratedMessage> pbList = fieldValue;
// Copy the mapped values to a List to avoid redundant cloning (since
// PbList.addAll iterates over its argument twice).
_ensureRepeatedField(fi)
.addAll(new List.from(fieldValue.map(_cloneMessage)));
.addAll(new List.from(pbList.map(_cloneMessage)));
} else {
_ensureRepeatedField(fi).addAll(fieldValue);
// fieldValue must be at least a PbList.
PbList pbList = fieldValue;
_ensureRepeatedField(fi).addAll(pbList);
}
return;
}
Expand Down
55 changes: 32 additions & 23 deletions lib/src/protobuf/generated_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -276,56 +276,65 @@ abstract class GeneratedMessage {
///
/// Throws an [:ArgumentError:] if [value] is [:null:]. To clear a field of
/// it's current value, use [clearField] instead.
void setField(int tagNumber, value) => _fieldSet._setField(tagNumber, value);
void setField(int tagNumber, value) {
_fieldSet._setField(tagNumber, value);
return; // ignore: dead_code
return; // ignore: dead_code
}

/// For generated code only.
T $_get<T>(int index, T defaultValue) =>
_fieldSet._$get<T>(index, defaultValue);

/// For generated code only.
T $_getN<T>(int index) => _fieldSet._$getN<T>(index);

/// For generated code only.
String $_getS(int index, String defaultValue) =>
_fieldSet._$getS(index, defaultValue);

/// For generated code only.
T $_get<T>(int index, int tagNumber, T defaultValue) =>
_fieldSet._$get<T>(index, tagNumber, defaultValue);
Int64 $_getI64(int index) => _fieldSet._$getI64(index);

/// For generated code only.
bool $_has(int index, int tagNumber) => _fieldSet._$has(index, tagNumber);
bool $_has(int index) => _fieldSet._$has(index);

/// For generated code only.
void $_setBool(int index, int tagNumber, bool value) =>
_fieldSet._$set(index, tagNumber, value);
void $_setBool(int index, bool value) => _fieldSet._$set(index, value);

/// For generated code only.
void $_setBytes(int index, int tagNumber, List<int> value) =>
_fieldSet._$set(index, tagNumber, value);
void $_setBytes(int index, List<int> value) => _fieldSet._$set(index, value);

/// For generated code only.
void $_setString(int index, int tagNumber, String value) =>
_fieldSet._$set(index, tagNumber, value);
void $_setString(int index, String value) => _fieldSet._$set(index, value);

/// For generated code only.
void $_setFloat(int index, int tagNumber, double value) {
void $_setFloat(int index, double value) {
if (value == null || !_isFloat32(value)) {
_fieldSet._$check(tagNumber, value);
_fieldSet._$check(index, value);
}
_fieldSet._$set(index, tagNumber, value);
_fieldSet._$set(index, value);
}

/// For generated code only.
void $_setDouble(int index, int tagNumber, double value) =>
_fieldSet._$set(index, tagNumber, value);
void $_setDouble(int index, double value) => _fieldSet._$set(index, value);

/// For generated code only.
void $_setSignedInt32(int index, int tagNumber, int value) {
void $_setSignedInt32(int index, int value) {
if (value == null || !_isSigned32(value)) {
_fieldSet._$check(tagNumber, value);
_fieldSet._$check(index, value);
}
_fieldSet._$set(index, tagNumber, value);
_fieldSet._$set(index, value);
}

/// For generated code only.
void $_setUnsignedInt32(int index, int tagNumber, int value) {
void $_setUnsignedInt32(int index, int value) {
if (value == null || !_isUnsigned32(value)) {
_fieldSet._$check(tagNumber, value);
_fieldSet._$check(index, value);
}
_fieldSet._$set(index, tagNumber, value);
_fieldSet._$set(index, value);
}

/// For generated code only.
void $_setInt64(int index, int tagNumber, Int64 value) =>
_fieldSet._$set(index, tagNumber, value);
void $_setInt64(int index, Int64 value) => _fieldSet._$set(index, value);
}
Loading

0 comments on commit e1d646f

Please sign in to comment.