Skip to content

Commit

Permalink
add hooks so generated code can pass in check item function
Browse files Browse the repository at this point in the history
for clarity, separate out repeated field info construction

BUG=
[email protected]

Review URL: https://chromiumcodereview.appspot.com//1283113003.
  • Loading branch information
Brian Slesinsky committed Aug 13, 2015
1 parent 5e603ae commit e62498f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
23 changes: 19 additions & 4 deletions lib/src/protobuf/builder_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ class BuilderInfo {
name, tagNumber, fieldType, defaultOrMaker, subBuilder, valueOf);
}

void addRepeated(int tagNumber, String name, int fieldType,
CheckFunc check,
CreateBuilderFunc subBuilder,
ValueOfFunc valueOf) {
fieldInfo[tagNumber] = byName[name] = new FieldInfo.repeated(
name, tagNumber, fieldType, check, subBuilder, valueOf);
}

void a(int tagNumber, String name, int fieldType,
[dynamic defaultOrMaker,
CreateBuilderFunc subBuilder,
Expand All @@ -40,7 +48,7 @@ class BuilderInfo {
}

// Repeated message.
// TODO(antonm): change the order of CreateBuilderFunc and MakeDefaultFunc.
// TODO(skybrian): migrate to pp() and remove.
void m(int tagNumber, String name,
CreateBuilderFunc subBuilder, MakeDefaultFunc makeDefault) {
add(tagNumber, name, FieldType._REPEATED_MESSAGE,
Expand All @@ -49,9 +57,16 @@ class BuilderInfo {

// Repeated, not a message, group, or enum.
void p(int tagNumber, String name, int fieldType) {
// The fieldType entirely determines the check function.
var makeDefault = () => new PbList.forFieldType(fieldType);
add(tagNumber, name, fieldType, makeDefault, null, null);
assert(!_isGroupOrMessage(fieldType) && !_isEnum(fieldType));
addRepeated(tagNumber, name, fieldType,
getCheckFunction(fieldType), null, null);
}

// Repeated message, group, or enum.
void pp(int tagNumber, String name, int fieldType, CheckFunc check,
[CreateBuilderFunc subBuilder, ValueOfFunc valueOf]) {
assert(_isGroupOrMessage(fieldType) || _isEnum(fieldType));
addRepeated(tagNumber, name, fieldType, check, subBuilder, valueOf);
}

bool containsTagNumber(int tagNumber) => fieldInfo.containsKey(tagNumber);
Expand Down
6 changes: 6 additions & 0 deletions lib/src/protobuf/extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class Extension extends FieldInfo {
ValueOfFunc valueOf]) :
super(name, tagNumber, fieldType, defaultOrMaker, subBuilder, valueOf);

Extension.repeated(this.extendee, String name, int tagNumber, int fieldType,
CheckFunc check,
[CreateBuilderFunc subBuilder,
ValueOfFunc valueOf]) :
super.repeated(name, tagNumber, fieldType, check, subBuilder, valueOf);

int get hashCode => extendee.hashCode * 31 + tagNumber;

bool operator ==(other) {
Expand Down
7 changes: 7 additions & 0 deletions lib/src/protobuf/field_error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ String _getFieldError(int fieldType, var value) {
}
}

// entry points for generated code

// generated checkItem for message, group, enum calls this
void checkItemFailed(val, String className) {
throw new ArgumentError('Value ($val) is not an instance of ${className}');
}

/// Returns a function for validating items in a repeated field.
///
/// For enum, group, and message fields, the check is only approximate,
Expand Down
33 changes: 32 additions & 1 deletion lib/src/protobuf/field_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,47 @@ class FieldInfo {
final String name;
final int tagNumber;
final int type;

// Constructs the default value of a field.
// TODO(skybrian): stop using this for repeated fields.
final MakeDefaultFunc makeDefault;

// Creates an empty message or group when decoding a message.
// Not used for other types.
// see GeneratedMessage._getEmptyMessage
final CreateBuilderFunc subBuilder;

// Looks up the enum value given its integer code.
// (Not used for other types.)
// see GeneratedMessage._getValueOfFunc
final ValueOfFunc valueOf;

// Verifies an item being added to a repeated field
// (Not used for non-repeated fields.)
final CheckFunc check;

FieldInfo(this.name, this.tagNumber, int type,
[dynamic defaultOrMaker,
this.subBuilder,
this.valueOf])
: this.type = type,
this.makeDefault = findMakeDefault(type, defaultOrMaker);
this.makeDefault = findMakeDefault(type, defaultOrMaker),
this.check = null {
assert(!_isGroupOrMessage(type) || subBuilder != null);
assert(!_isEnum(type) || valueOf != null);
}

FieldInfo.repeated(this.name, this.tagNumber, int type,
CheckFunc check, this.subBuilder,
[this.valueOf])
: this.type = type, this.check = check,
this.makeDefault = (() => new PbList(check: check)) {
assert(name != null);
assert(tagNumber != null);
assert(_isRepeated(type));
assert(check != null);
assert(!_isEnum(type) || valueOf != null);
}

static MakeDefaultFunc findMakeDefault(int type, dynamic defaultOrMaker) {
if (defaultOrMaker == null) return FieldType._defaultForType(type);
Expand Down
4 changes: 3 additions & 1 deletion lib/src/protobuf/pb_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class PbList<E> extends Object with ListMixin<E> implements List<E> {
final List<E> _wrappedList;
final CheckFunc check;

PbList({this.check: _checkNotNull}) : _wrappedList = <E>[];
PbList({this.check: _checkNotNull}) : _wrappedList = <E>[] {
assert(check != null);
}

PbList.from(List from)
: _wrappedList = new List<E>.from(from),
Expand Down

0 comments on commit e62498f

Please sign in to comment.