Don't create BuilderInfo object for map entries in PBMap constructor. (#179)
diff --git a/protobuf/CHANGELOG.md b/protobuf/CHANGELOG.md
index 395691e..79d0ad6 100644
--- a/protobuf/CHANGELOG.md
+++ b/protobuf/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.12.0
+
+* Breaking change: Changed `BuilderInfo.m()` to take class and package name of the protobuf message representing the map
+ entry. Also changed `BuilderInfo.addMapField` as well as the constructors `PbMap` and `MapFieldInfo.map` to take a map
+ entry BuilderInfo object.
+
+ This mostly affects generated code, which should now be built with protoc_plugin 15.0.0 or newer.
+
+ With this change we avoid creating a map entry BuilderInfo object for each PbMap instance, instead it is passed
+ through the static BuilderInfo object in the generated subclasses of GeneratedMessage.
+
## 0.11.0
* Breaking change: changed semantics of `GeneratedMessage.toBuilder()` to only make a shallow copy.
@@ -5,7 +16,7 @@
`GeneratedMessage` has a new abstract method: `createEmptyInstance()` that subclasses must
implement.
- Proto files must be rebuilt using protoc_plugin 0.15.0 or newer.
+ Proto files must be rebuilt using protoc_plugin 14.0.0 or newer.
## 0.10.8
diff --git a/protobuf/lib/src/protobuf/builder_info.dart b/protobuf/lib/src/protobuf/builder_info.dart
index 513ec4e..c63c2b1 100644
--- a/protobuf/lib/src/protobuf/builder_info.dart
+++ b/protobuf/lib/src/protobuf/builder_info.dart
@@ -34,17 +34,11 @@
defaultOrMaker, subBuilder, valueOf, enumValues));
}
- void addMapField<K, V>(
- int tagNumber,
- String name,
- int keyFieldType,
- int valueFieldType,
- CreateBuilderFunc valueCreator,
- ValueOfFunc valueOf,
- List<ProtobufEnum> enumValues) {
+ void addMapField<K, V>(int tagNumber, String name, int keyFieldType,
+ int valueFieldType, BuilderInfo mapEntryBuilderInfo) {
var index = byIndex.length;
_addField(MapFieldInfo<K, V>.map(name, tagNumber, index, PbFieldType.M,
- keyFieldType, valueFieldType, valueCreator, valueOf, enumValues));
+ keyFieldType, valueFieldType, mapEntryBuilderInfo));
}
void addRepeated<T>(
@@ -134,12 +128,20 @@
}
// Map field.
- void m<K, V>(int tagNumber, String name, int keyFieldType, int valueFieldType,
+ void m<K, V>(int tagNumber, String name, String entryClassName,
+ int keyFieldType, int valueFieldType,
[CreateBuilderFunc valueCreator,
ValueOfFunc valueOf,
- List<ProtobufEnum> enumValues]) {
- addMapField<K, V>(tagNumber, name, keyFieldType, valueFieldType,
- valueCreator, valueOf, enumValues);
+ List<ProtobufEnum> enumValues,
+ PackageName packageName = const PackageName('')]) {
+ BuilderInfo mapEntryBuilderInfo = BuilderInfo(entryClassName,
+ package: packageName)
+ ..add(PbMap._keyFieldNumber, 'key', keyFieldType, null, null, null, null)
+ ..add(PbMap._valueFieldNumber, 'value', valueFieldType, null,
+ valueCreator, valueOf, enumValues);
+
+ addMapField<K, V>(
+ tagNumber, name, keyFieldType, valueFieldType, mapEntryBuilderInfo);
}
bool containsTagNumber(int tagNumber) => fieldInfo.containsKey(tagNumber);
diff --git a/protobuf/lib/src/protobuf/field_info.dart b/protobuf/lib/src/protobuf/field_info.dart
index c977a96..0f7eb4b 100644
--- a/protobuf/lib/src/protobuf/field_info.dart
+++ b/protobuf/lib/src/protobuf/field_info.dart
@@ -8,6 +8,9 @@
class FieldInfo<T> {
FrozenPbList<T> _emptyList;
+ // BuilderInfo used when creating a field set for a map field.
+ final BuilderInfo _mapEntryBuilderInfo;
+
final String name;
final int tagNumber;
final int index; // index of the field's value. Null for extensions.
@@ -39,7 +42,8 @@
[dynamic defaultOrMaker, this.subBuilder, this.valueOf, this.enumValues])
: this.type = type,
this.makeDefault = findMakeDefault(type, defaultOrMaker),
- this.check = null {
+ this.check = null,
+ _mapEntryBuilderInfo = null {
assert(type != 0);
assert(!_isGroupOrMessage(type) || subBuilder != null);
assert(!_isEnum(type) || valueOf != null);
@@ -49,7 +53,8 @@
this.check, this.subBuilder,
[this.valueOf, this.enumValues])
: this.type = type,
- this.makeDefault = (() => new PbList<T>(check: check)) {
+ this.makeDefault = (() => new PbList<T>(check: check)),
+ _mapEntryBuilderInfo = null {
assert(name != null);
assert(tagNumber != null);
assert(_isRepeated(type));
@@ -59,7 +64,11 @@
FieldInfo._map(
this.name, this.tagNumber, this.index, int type, this.makeDefault,
- [dynamic defaultOrMaker, this.subBuilder, this.valueOf, this.enumValues])
+ [dynamic defaultOrMaker,
+ this.subBuilder,
+ this.valueOf,
+ this.enumValues,
+ this._mapEntryBuilderInfo])
: this.type = type,
this.check = null {
assert(name != null);
@@ -169,19 +178,19 @@
CreateBuilderFunc valueCreator;
MapFieldInfo.map(String name, int tagNumber, int index, int type,
- this.keyFieldType, this.valueFieldType,
- [this.valueCreator, ValueOfFunc valueOf, List<ProtobufEnum> enumValues])
+ this.keyFieldType, this.valueFieldType, BuilderInfo mapEntryBuilderInfo)
: super._map(
name,
tagNumber,
index,
type,
- () => PbMap<K, V>(keyFieldType, valueFieldType, valueCreator,
- valueOf, enumValues),
+ () =>
+ PbMap<K, V>(keyFieldType, valueFieldType, mapEntryBuilderInfo),
null,
null,
- valueOf,
- enumValues) {
+ null,
+ null,
+ mapEntryBuilderInfo) {
assert(name != null);
assert(tagNumber != null);
assert(_isMapField(type));
diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart
index 6cd4e7c..4723b04 100644
--- a/protobuf/lib/src/protobuf/field_set.dart
+++ b/protobuf/lib/src/protobuf/field_set.dart
@@ -198,8 +198,8 @@
Map<K, V> _getDefaultMap<K, V>(MapFieldInfo<K, V> fi) {
assert(fi.isMapField);
if (_isReadOnly)
- return PbMap<K, V>.unmodifiable(PbMap<K, V>(fi.keyFieldType,
- fi.valueFieldType, fi.valueCreator, fi.valueOf, fi.enumValues));
+ return PbMap<K, V>.unmodifiable(PbMap<K, V>(
+ fi.keyFieldType, fi.valueFieldType, fi._mapEntryBuilderInfo));
var value = fi._createMapField(_message);
_setNonExtensionFieldUnchecked(fi, value);
diff --git a/protobuf/lib/src/protobuf/generated_message.dart b/protobuf/lib/src/protobuf/generated_message.dart
index 23f46a2..c78e11d 100644
--- a/protobuf/lib/src/protobuf/generated_message.dart
+++ b/protobuf/lib/src/protobuf/generated_message.dart
@@ -270,8 +270,8 @@
/// Creates a Map representing a map field.
Map<K, V> createMapField<K, V>(int tagNumber, MapFieldInfo<K, V> fi) {
- return PbMap<K, V>(fi.keyFieldType, fi.valueFieldType, fi.valueCreator,
- fi.valueOf, fi.enumValues);
+ return PbMap<K, V>(
+ fi.keyFieldType, fi.valueFieldType, fi._mapEntryBuilderInfo);
}
/// Returns the value of a field, ignoring any defaults.
diff --git a/protobuf/lib/src/protobuf/pb_map.dart b/protobuf/lib/src/protobuf/pb_map.dart
index f991df4..d8a5110 100644
--- a/protobuf/lib/src/protobuf/pb_map.dart
+++ b/protobuf/lib/src/protobuf/pb_map.dart
@@ -16,16 +16,9 @@
bool _isReadonly = false;
_FieldSet _entryFieldSet;
- PbMap(this.keyFieldType, this.valueFieldType,
- [CreateBuilderFunc valueCreator,
- ValueOfFunc valueOf,
- List<ProtobufEnum> enumValues])
+ PbMap(this.keyFieldType, this.valueFieldType, BuilderInfo entryBuilderInfo)
: _wrappedMap = <K, V>{} {
- BuilderInfo entryInfo = new BuilderInfo("entry")
- ..add(_keyFieldNumber, "key", keyFieldType, null, null, null, null)
- ..add(_valueFieldNumber, "value", valueFieldType, null, valueCreator,
- valueOf, enumValues);
- _entryFieldSet = new _FieldSet(null, entryInfo, null);
+ _entryFieldSet = new _FieldSet(null, entryBuilderInfo, null);
}
PbMap.unmodifiable(PbMap other)
diff --git a/protobuf/pubspec.yaml b/protobuf/pubspec.yaml
index 01dc101..05ba43e 100644
--- a/protobuf/pubspec.yaml
+++ b/protobuf/pubspec.yaml
@@ -1,5 +1,5 @@
name: protobuf
-version: 0.11.0
+version: 0.12.0
author: Dart Team <misc@dartlang.org>
description: >
Runtime library for protocol buffers support.
diff --git a/protoc_plugin/CHANGELOG.md b/protoc_plugin/CHANGELOG.md
index 291e204..bc3e592 100644
--- a/protoc_plugin/CHANGELOG.md
+++ b/protoc_plugin/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 15.0.0
+
+* Breaking change: Changed BuilderInfo call for map fields to include the BuilderInfo object for map entries.
+ Generated files require package:protobuf version 0.12.0 or newer.
+
## 14.0.1
* Remove the benchmark from the protoc_package. It now lives in
diff --git a/protoc_plugin/lib/message_generator.dart b/protoc_plugin/lib/message_generator.dart
index df96853..8a3b8f1 100644
--- a/protoc_plugin/lib/message_generator.dart
+++ b/protoc_plugin/lib/message_generator.dart
@@ -290,7 +290,8 @@
';', () {
for (ProtobufField field in _fieldList) {
var dartFieldName = field.memberNames.fieldName;
- out.println(field.generateBuilderInfoCall(fileGen, dartFieldName));
+ out.println(
+ field.generateBuilderInfoCall(fileGen, dartFieldName, package));
}
for (int oneof = 0; oneof < _oneofFields.length; oneof++) {
diff --git a/protoc_plugin/lib/protobuf_field.dart b/protoc_plugin/lib/protobuf_field.dart
index 3482161..e055c01 100644
--- a/protoc_plugin/lib/protobuf_field.dart
+++ b/protoc_plugin/lib/protobuf_field.dart
@@ -115,7 +115,8 @@
/// Returns Dart code adding this field to a BuilderInfo object.
/// The call will start with ".." and a method name.
/// [fileGen] represents the .proto file where the code will be evaluated.
- String generateBuilderInfoCall(FileGenerator fileGen, String dartFieldName) {
+ String generateBuilderInfoCall(
+ FileGenerator fileGen, String dartFieldName, String package) {
String quotedName = "'$dartFieldName'";
String type = baseType.getDartType(fileGen);
@@ -127,18 +128,18 @@
String valueType = value.baseType.getDartType(fileGen);
String keyTypeConstant = key.typeConstant;
String valTypeConstant = value.typeConstant;
+ String valueCreator = (value.baseType.isMessage || value.baseType.isGroup)
+ ? '$valueType.create'
+ : 'null';
+ String valueOf = value.baseType.isEnum ? '$valueType.valueOf' : 'null';
+ String enumValues = value.baseType.isEnum ? '$valueType.values' : 'null';
+ String mapEntryClassName = "'${generator.messageName}'";
+ String packageClause = package == ''
+ ? ''
+ : ", const $_protobufImportPrefix.PackageName(\'$package\')";
- if (value.baseType.isMessage || value.baseType.isGroup) {
- return '..m<$keyType, $valueType>($number, $quotedName, '
- '$keyTypeConstant, $valTypeConstant, $valueType.create)';
- }
- if (value.baseType.isEnum) {
- return '..m<$keyType, $valueType>($number, $quotedName, '
- '$keyTypeConstant, $valTypeConstant, null, $valueType.valueOf, '
- '$valueType.values)';
- }
- return '..m<$keyType, $valueType>($number, $quotedName, '
- '$keyTypeConstant, $valTypeConstant)';
+ return '..m<$keyType, $valueType>($number, $quotedName, $mapEntryClassName,'
+ '$keyTypeConstant, $valTypeConstant, $valueCreator, $valueOf, $enumValues $packageClause)';
}
if (isRepeated) {
diff --git a/protoc_plugin/pubspec.yaml b/protoc_plugin/pubspec.yaml
index c5c5e30..debcc92 100644
--- a/protoc_plugin/pubspec.yaml
+++ b/protoc_plugin/pubspec.yaml
@@ -1,5 +1,5 @@
name: protoc_plugin
-version: 14.0.1
+version: 15.0.0
author: Dart Team <misc@dartlang.org>
description: Protoc compiler plugin to generate Dart code
homepage: https://github.com/dart-lang/protobuf
@@ -10,7 +10,7 @@
dependencies:
fixnum: ^0.10.5
path: ^1.0.0
- protobuf: ^0.11.0
+ protobuf: ^0.12.0
dart_style: ^1.0.6
dev_dependencies: