Skip to content

Commit

Permalink
Adds the nullable option which allows to use nullable types in addi…
Browse files Browse the repository at this point in the history
…tion to hazzers.
  • Loading branch information
Johyn Papin committed Jan 5, 2023
1 parent dd04535 commit f76f18c
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 17 deletions.
14 changes: 14 additions & 0 deletions protobuf/lib/meta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const GeneratedMessage_reservedNames = <String>[
'runtimeType',
'setExtension',
'setField',
'setFieldNullable',
'toBuilder',
'toDebugString',
'toProto3Json',
Expand All @@ -60,25 +61,38 @@ const GeneratedMessage_reservedNames = <String>[
'writeToJsonMap',
r'$_ensure',
r'$_get',
r'$_getNullable',
r'$_getI64',
r'$_getI64Nullable',
r'$_getList',
r'$_getMap',
r'$_getN',
r'$_getB',
r'$_getBF',
r'$_getBNullable',
r'$_getI',
r'$_getIZ',
r'$_getINullable',
r'$_getS',
r'$_getSZ',
r'$_getSNullable',
r'$_has',
r'$_setBool',
r'$_setBoolNullable',
r'$_setBytes',
r'$_setBytesNullable',
r'$_setDouble',
r'$_setDoubleNullable',
r'$_setFloat',
r'$_setFloatNullable',
r'$_setInt64',
r'$_setInt64Nullable',
r'$_setSignedInt32',
r'$_setSignedInt32Nullable',
r'$_setString',
r'$_setStringNullable',
r'$_setUnsignedInt32',
r'$_setUnsignedInt32Nullable',
r'$_whichOneof',
];

Expand Down
58 changes: 58 additions & 0 deletions protobuf/lib/src/protobuf/field_set.dart
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,38 @@ class _FieldSet {
_setNonExtensionFieldUnchecked(meta, fi, value);
}

/// Sets a non-repeated nullable field with error-checking.
///
/// Works for both extended and non-extended fields.
/// Suitable for public API.
void _setFieldNullable(int tagNumber, Object? value) {
final meta = _meta;
var fi = _nonExtensionInfo(meta, tagNumber);
if (fi == null) {
final extensions = _extensions;
if (extensions == null) {
throw ArgumentError('tag $tagNumber not defined in $_messageName');
}
if (value == null) {
_clearField(tagNumber);
return;
}
extensions._setField(tagNumber, value);
return;
}

if (fi.isRepeated) {
throw ArgumentError(_setFieldFailedMessage(
fi, value, 'repeating field (use get + .add())'));
}
if (value == null) {
_clearField(tagNumber);
return;
}
_validateField(fi, value);
_setNonExtensionFieldUnchecked(meta, fi, value);
}

/// Sets a non-repeated field without validating it.
///
/// Works for both extended and non-extended fields.
Expand Down Expand Up @@ -431,6 +463,9 @@ class _FieldSet {
/// `false`.
bool _$getBF(int index) => _values[index] ?? false;

/// The implementation of a generated getter for nullable `bool` fields.
bool? _$getBNullable(int index) => _values[index];

/// The implementation of a generated getter for int fields.
int _$getI(int index, int? defaultValue) {
var value = _values[index];
Expand All @@ -445,6 +480,9 @@ class _FieldSet {
/// fixed32, sfixed32) that default to `0`.
int _$getIZ(int index) => _values[index] ?? 0;

/// The implementation of a generated getter for nullable int fields.
int? _$getINullable(int index) => _values[index];

/// The implementation of a generated getter for String fields.
String _$getS(int index, String? defaultValue) {
var value = _values[index];
Expand All @@ -459,13 +497,19 @@ class _FieldSet {
/// the empty string.
String _$getSZ(int index) => _values[index] ?? '';

/// The implementation of a generated getter for nullable String fields.
String? _$getSNullable(int index) => _values[index];

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

/// The implementation of a generated getter for nullable Int64 fields.
Int64? _$getI64Nullable(int index) => _values[index];

/// The implementation of a generated 'has' method.
bool _$has(int index) {
var value = _values[index];
Expand Down Expand Up @@ -504,11 +548,25 @@ class _FieldSet {
_values[index] = value;
}

void _$setNullable(int index, Object? value) {
assert(!_nonExtensionInfoByIndex(index).isRepeated);
assert(value == null || _$check(index, value));
if (value == null) {
_clearField(_meta.byIndex[index].tagNumber);
return;
}

_$set(index, value);
}

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

/// The implementation of a generated nullable getter.
T _$getNullable<T>(int index) => _values[index];

// Bulk operations reading or writing multiple fields

void _clear() {
Expand Down
81 changes: 81 additions & 0 deletions protobuf/lib/src/protobuf/generated_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,15 @@ abstract class GeneratedMessage {
_fieldSet._setField(tagNumber, value);
}

/// Sets the value of a field by its [tagNumber].
///
/// Throws an [ArgumentError] if [value] does not match the type associated
/// with [tagNumber].
@pragma('dart2js:noInline')
void setFieldNullable(int tagNumber, Object? value) {
_fieldSet._setFieldNullable(tagNumber, value);
}

/// For generated code only.
/// @nodoc
T $_get<T>(int index, T defaultValue) =>
Expand All @@ -411,6 +420,10 @@ abstract class GeneratedMessage {
/// @nodoc
T $_getN<T>(int index) => _fieldSet._$getND(index);

/// For generated code only.
/// @nodoc
T $_getNullable<T>(int index) => _fieldSet._$getNullable<T>(index);

/// For generated code only.
/// @nodoc
T $_ensure<T>(int index) => _fieldSet._$ensure<T>(index);
Expand All @@ -432,6 +445,10 @@ abstract class GeneratedMessage {
/// @nodoc
bool $_getBF(int index) => _fieldSet._$getBF(index);

/// For generated code only.
/// @nodoc
bool? $_getBNullable(int index) => _fieldSet._$getBNullable(index);

/// For generated code only.
/// @nodoc
int $_getI(int index, int defaultValue) =>
Expand All @@ -441,6 +458,10 @@ abstract class GeneratedMessage {
/// @nodoc
int $_getIZ(int index) => _fieldSet._$getIZ(index);

/// For generated code only.
/// @nodoc
int? $_getINullable(int index) => _fieldSet._$getINullable(index);

/// For generated code only.
/// @nodoc
String $_getS(int index, String defaultValue) =>
Expand All @@ -450,10 +471,18 @@ abstract class GeneratedMessage {
/// @nodoc
String $_getSZ(int index) => _fieldSet._$getSZ(index);

/// For generated code only.
/// @nodoc
String? $_getSNullable(int index) => _fieldSet._$getSNullable(index);

/// For generated code only.
/// @nodoc
Int64 $_getI64(int index) => _fieldSet._$getI64(index);

/// For generated code only.
/// @nodoc
Int64? $_getI64Nullable(int index) => _fieldSet._$getI64Nullable(index);

/// For generated code only.
/// @nodoc
bool $_has(int index) => _fieldSet._$has(index);
Expand All @@ -462,14 +491,29 @@ abstract class GeneratedMessage {
/// @nodoc
void $_setBool(int index, bool value) => _fieldSet._$set(index, value);

/// For generated code only.
/// @nodoc
void $_setBoolNullable(int index, bool? value) =>
_fieldSet._$setNullable(index, value);

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

/// For generated code only.
/// @nodoc
void $_setBytesNullable(int index, List<int>? value) =>
_fieldSet._$setNullable(index, value);

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

/// For generated code only.
/// @nodoc
void $_setStringNullable(int index, String? value) =>
_fieldSet._$setNullable(index, value);

/// For generated code only.
/// @nodoc
void $_setFloat(int index, double value) {
Expand All @@ -480,10 +524,24 @@ abstract class GeneratedMessage {
_fieldSet._$set(index, value);
}

/// For generated code only.
/// @nodoc
void $_setFloatNullable(int index, double? value) {
if (value != null && !_isFloat32(value)) {
_fieldSet._$check(index, value);
}
_fieldSet._$setNullable(index, value);
}

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

/// For generated code only.
/// @nodoc
void $_setDoubleNullable(int index, double? value) =>
_fieldSet._$setNullable(index, value);

/// For generated code only.
/// @nodoc
void $_setSignedInt32(int index, int value) {
Expand All @@ -494,6 +552,15 @@ abstract class GeneratedMessage {
_fieldSet._$set(index, value);
}

/// For generated code only.
/// @nodoc
void $_setSignedInt32Nullable(int index, int? value) {
if (value != null && !_isSigned32(value)) {
_fieldSet._$check(index, value);
}
_fieldSet._$setNullable(index, value);
}

/// For generated code only.
/// @nodoc
void $_setUnsignedInt32(int index, int value) {
Expand All @@ -504,10 +571,24 @@ abstract class GeneratedMessage {
_fieldSet._$set(index, value);
}

/// For generated code only.
/// @nodoc
void $_setUnsignedInt32Nullable(int index, int? value) {
if (value != null && !_isUnsigned32(value)) {
_fieldSet._$check(index, value);
}
_fieldSet._$setNullable(index, value);
}

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

/// For generated code only.
/// @nodoc
void $_setInt64Nullable(int index, Int64? value) =>
_fieldSet._$setNullable(index, value);

// Support for generating a read-only default singleton instance.

static final Map<Function?, _SingletonMaker<GeneratedMessage>>
Expand Down
10 changes: 8 additions & 2 deletions protoc_plugin/lib/src/file_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,14 @@ class FileGenerator extends ProtobufContainer {
descriptor.enumType[i], this, usedTopLevelNames, i));
}
for (var i = 0; i < descriptor.messageType.length; i++) {
messageGenerators.add(MessageGenerator.topLevel(descriptor.messageType[i],
this, declaredMixins, defaultMixin, usedTopLevelNames, i));
messageGenerators.add(MessageGenerator.topLevel(
descriptor.messageType[i],
this,
declaredMixins,
defaultMixin,
usedTopLevelNames,
i,
options.useNullable));
}
for (var i = 0; i < descriptor.extension.length; i++) {
extensionGenerators.add(ExtensionGenerator.topLevel(
Expand Down
Loading

0 comments on commit f76f18c

Please sign in to comment.