diff --git a/protobuf/lib/src/protobuf/builder_info.dart b/protobuf/lib/src/protobuf/builder_info.dart index 95fa3b003..91913fbac 100644 --- a/protobuf/lib/src/protobuf/builder_info.dart +++ b/protobuf/lib/src/protobuf/builder_info.dart @@ -44,7 +44,7 @@ class BuilderInfo { var index = byIndex.length; final fieldInfo = (tagNumber == 0) ? FieldInfo.dummy(index) - : FieldInfo(name, tagNumber, index, fieldType, + : FieldInfo(name, tagNumber, index, fieldType, defaultOrMaker: defaultOrMaker, subBuilder: subBuilder, valueOf: valueOf, @@ -77,7 +77,7 @@ class BuilderInfo { List enumValues, {String protoName}) { var index = byIndex.length; - _addField(FieldInfo.repeated( + _addField(FieldInfo>.repeated( name, tagNumber, index, fieldType, check, subBuilder, valueOf: valueOf, enumValues: enumValues, protoName: protoName)); } diff --git a/protobuf/lib/src/protobuf/extension.dart b/protobuf/lib/src/protobuf/extension.dart index cecc2574b..cea8be5f2 100644 --- a/protobuf/lib/src/protobuf/extension.dart +++ b/protobuf/lib/src/protobuf/extension.dart @@ -5,7 +5,7 @@ part of protobuf; /// An object representing an extension field. -class Extension extends FieldInfo { +class Extension extends FieldInfo { final String extendee; Extension(this.extendee, String name, int tagNumber, int fieldType, diff --git a/protobuf/lib/src/protobuf/extension_field_set.dart b/protobuf/lib/src/protobuf/extension_field_set.dart index e516a9d8d..9e3a755a2 100644 --- a/protobuf/lib/src/protobuf/extension_field_set.dart +++ b/protobuf/lib/src/protobuf/extension_field_set.dart @@ -36,7 +36,7 @@ class _ExtensionFieldSet { /// /// If it doesn't exist, creates the list and saves the extension. /// Suitable for public API and decoders. - List _ensureRepeatedField(Extension fi) { + List _ensureRepeatedField(Extension fi) { assert(!_isReadOnly); assert(fi.isRepeated); assert(fi.extendee == _parent._messageName); @@ -47,7 +47,7 @@ class _ExtensionFieldSet { return _addInfoAndCreateList(fi); } - List _getList(Extension fi) { + List _getList(Extension fi) { var value = _values[fi.tagNumber]; if (value != null) return value as List; if (_isReadOnly) return List.unmodifiable(const []); diff --git a/protobuf/lib/src/protobuf/field_info.dart b/protobuf/lib/src/protobuf/field_info.dart index 1a52faf34..af2263232 100644 --- a/protobuf/lib/src/protobuf/field_info.dart +++ b/protobuf/lib/src/protobuf/field_info.dart @@ -5,7 +5,8 @@ part of protobuf; /// An object representing a protobuf message field. -class FieldInfo { +/// For a repeated field S is List for a non-repeated field S=T. +class FieldInfo { FrozenPbList _emptyList; /// Name of this field as the `json_name` reported by protoc. @@ -24,9 +25,9 @@ class FieldInfo { // Constructs the default value of a field. // (Only used for repeated fields where check is null.) - final MakeDefaultFunc makeDefault; + final U Function() makeDefault; - // Creates an empty message or group when decoding a message. + // Creates an empty message when decoding a message. // Not used for other types. // see GeneratedMessage._getEmptyMessage final CreateBuilderFunc subBuilder; @@ -74,7 +75,7 @@ class FieldInfo { FieldInfo.repeated(this.name, this.tagNumber, this.index, this.type, this.check, this.subBuilder, {this.valueOf, this.enumValues, String protoName}) - : makeDefault = (() => PbList(check: check)), + : makeDefault = (() => PbList(check: check) as U), protoName = protoName ?? _unCamelCase(name) { assert(name != null); assert(tagNumber != null); @@ -83,7 +84,7 @@ class FieldInfo { assert(!_isEnum(type) || valueOf != null); } - static MakeDefaultFunc findMakeDefault(int type, dynamic defaultOrMaker) { + static S Function() findMakeDefault(int type, dynamic defaultOrMaker) { if (defaultOrMaker == null) return PbFieldType._defaultForType(type); if (defaultOrMaker is MakeDefaultFunc) return defaultOrMaker; return () => defaultOrMaker; @@ -101,9 +102,9 @@ class FieldInfo { /// Returns a read-only default value for a field. /// (Unlike getField, doesn't create a repeated field.) - dynamic get readonlyDefault { + U get readonlyDefault { if (isRepeated) { - return _emptyList ??= FrozenPbList._([]); + return (_emptyList ??= FrozenPbList._([])) as U; } return makeDefault(); } @@ -165,19 +166,19 @@ class FieldInfo { /// be overridden by a mixin. List _createRepeatedField(GeneratedMessage m) { assert(isRepeated); - return m.createRepeatedField(tagNumber, this); + return m.createRepeatedField(tagNumber, this); } /// Same as above, but allow a tighter typed List to be created. List _createRepeatedFieldWithType(GeneratedMessage m) { assert(isRepeated); - return m.createRepeatedField(tagNumber, this); + return m.createRepeatedField(tagNumber, this); } /// Convenience method to thread this FieldInfo's reified type parameter to /// _FieldSet._ensureRepeatedField. List _ensureRepeatedField(_FieldSet fs) { - return fs._ensureRepeatedField(this); + return fs._ensureRepeatedField(this); } @override @@ -191,7 +192,7 @@ String _unCamelCase(String name) { _upperCase, (match) => '_${match.group(0).toLowerCase()}'); } -class MapFieldInfo extends FieldInfo> { +class MapFieldInfo extends FieldInfo, PbMap> { final int keyFieldType; final int valueFieldType; diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart index 11df0c3db..5ff1635d2 100644 --- a/protobuf/lib/src/protobuf/field_set.dart +++ b/protobuf/lib/src/protobuf/field_set.dart @@ -236,7 +236,7 @@ class _FieldSet { return value; } - List _getDefaultList(FieldInfo fi) { + List _getDefaultList(FieldInfo fi) { assert(fi.isRepeated); if (_isReadOnly) return List.unmodifiable(const []); @@ -359,11 +359,11 @@ class _FieldSet { /// Creates and stores the repeated field if it doesn't exist. /// If it's an extension and the list doesn't exist, validates and stores it. /// Suitable for decoders. - List _ensureRepeatedField(FieldInfo fi) { + List _ensureRepeatedField(FieldInfo fi) { assert(!_isReadOnly); assert(fi.isRepeated); if (fi.index == null) { - return _ensureExtensions()._ensureRepeatedField(fi); + return _ensureExtensions()._ensureRepeatedField(fi as Extension); } var value = _getFieldOrNull(fi); if (value != null) return value as List; @@ -439,7 +439,7 @@ class _FieldSet { List _$getList(int index) { var value = _values[index]; if (value != null) return value as List; - return _getDefaultList(_nonExtensionInfoByIndex(index)); + return _getDefaultList(_nonExtensionInfoByIndex(index)); } /// The implementation of a generated getter for map fields. diff --git a/protobuf/lib/src/protobuf/generated_message.dart b/protobuf/lib/src/protobuf/generated_message.dart index 13f4dfb6b..e1309fff3 100644 --- a/protobuf/lib/src/protobuf/generated_message.dart +++ b/protobuf/lib/src/protobuf/generated_message.dart @@ -313,7 +313,7 @@ abstract class GeneratedMessage { /// Returns the value of [extension]. /// /// If not set, returns the extension's default value. - dynamic getExtension(Extension extension) { + U getExtension(Extension extension) { return _fieldSet._ensureExtensions()._getFieldOrDefault(extension); } @@ -327,7 +327,7 @@ abstract class GeneratedMessage { /// that the protobuf can be encoded correctly, the returned List must /// validate all items added to it. This can most easily be done /// using the FieldInfo.check function. - List createRepeatedField(int tagNumber, FieldInfo fi) { + List createRepeatedField(int tagNumber, FieldInfo fi) { return PbList(check: fi.check); } diff --git a/protobuf/lib/src/protobuf/readonly_message.dart b/protobuf/lib/src/protobuf/readonly_message.dart index 794f762ee..95cdb9107 100644 --- a/protobuf/lib/src/protobuf/readonly_message.dart +++ b/protobuf/lib/src/protobuf/readonly_message.dart @@ -17,7 +17,7 @@ abstract class ReadonlyMessageMixin { void clearField(int tagNumber) => _readonly('clearField'); - List createRepeatedField(int tagNumber, FieldInfo fi) { + List createRepeatedField(int tagNumber, FieldInfo fi) { _readonly('createRepeatedField'); return null; // not reached } diff --git a/protoc_plugin/lib/extension_generator.dart b/protoc_plugin/lib/extension_generator.dart index 2e30f3e41..9641ee927 100644 --- a/protoc_plugin/lib/extension_generator.dart +++ b/protoc_plugin/lib/extension_generator.dart @@ -97,6 +97,9 @@ class ExtensionGenerator { String name = _extensionName; var type = _field.baseType; var dartType = type.getDartType(fileGen); + var possiblyRepeatedDartType = + _field.isRepeated ? '$_coreImportPrefix.List<$dartType>' : dartType; + var typeArgs = '$dartType, $possiblyRepeatedDartType'; String invocation; List positionals = []; positionals.add("'$_extendedFullName'"); @@ -107,7 +110,7 @@ class ExtensionGenerator { Map named = {}; named['protoName'] = _field.quotedProtoName; if (_field.isRepeated) { - invocation = '$_protobufImportPrefix.Extension<$dartType>.repeated'; + invocation = '$_protobufImportPrefix.Extension<$typeArgs>.repeated'; named['check'] = '$_protobufImportPrefix.getCheckFunction(${_field.typeConstant})'; if (type.isMessage || type.isGroup) { @@ -117,7 +120,7 @@ class ExtensionGenerator { named['enumValues'] = '$dartType.values'; } } else { - invocation = '$_protobufImportPrefix.Extension<$dartType>'; + invocation = '$_protobufImportPrefix.Extension<$typeArgs>'; named['defaultOrMaker'] = _field.generateDefaultFunction(fileGen); if (type.isMessage || type.isGroup) { named['subBuilder'] = '$dartType.create'; @@ -129,13 +132,14 @@ class ExtensionGenerator { } assert(invocation != null); out.printAnnotated( - 'static final $_protobufImportPrefix.Extension $name = ' + 'static final $_protobufImportPrefix.Extension<$typeArgs> $name = ' '$invocation(${ProtobufField._formatArguments(positionals, named)});\n', [ NamedLocation( name: name, fieldPathSegment: List.from(fieldPath), - start: 'static final $_protobufImportPrefix.Extension '.length) + start: 'static final $_protobufImportPrefix.Extension<$typeArgs> ' + .length) ]); } } diff --git a/protoc_plugin/lib/src/dart_options.pb.dart b/protoc_plugin/lib/src/dart_options.pb.dart index ad2b620df..548f612bc 100644 --- a/protoc_plugin/lib/src/dart_options.pb.dart +++ b/protoc_plugin/lib/src/dart_options.pb.dart @@ -3,7 +3,7 @@ // source: dart_options.proto // // @dart = 2.3 -// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type +// ignore_for_file: camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type import 'dart:core' as $core; @@ -110,38 +110,34 @@ class Imports extends $pb.GeneratedMessage { } class Dart_options { - static final $pb.Extension imports = $pb.Extension( - 'google.protobuf.FileOptions', 'imports', 28125061, $pb.PbFieldType.OM, - defaultOrMaker: Imports.getDefault, subBuilder: Imports.create); - static final $pb.Extension defaultMixin = $pb.Extension<$core.String>( - 'google.protobuf.FileOptions', - 'defaultMixin', - 96128839, - $pb.PbFieldType.OS); - static final $pb.Extension mixin = $pb.Extension<$core.String>( - 'google.protobuf.MessageOptions', 'mixin', 96128839, $pb.PbFieldType.OS); - static final $pb.Extension overrideGetter = $pb.Extension<$core.bool>( - 'google.protobuf.FieldOptions', - 'overrideGetter', - 28205290, - $pb.PbFieldType.OB); - static final $pb.Extension overrideSetter = $pb.Extension<$core.bool>( - 'google.protobuf.FieldOptions', - 'overrideSetter', - 28937366, - $pb.PbFieldType.OB); - static final $pb.Extension overrideHasMethod = $pb.Extension<$core.bool>( - 'google.protobuf.FieldOptions', - 'overrideHasMethod', - 28937461, - $pb.PbFieldType.OB); - static final $pb.Extension overrideClearMethod = $pb.Extension<$core.bool>( - 'google.protobuf.FieldOptions', - 'overrideClearMethod', - 28907907, - $pb.PbFieldType.OB); - static final $pb.Extension dartName = $pb.Extension<$core.String>( - 'google.protobuf.FieldOptions', 'dartName', 28700919, $pb.PbFieldType.OS); + static final $pb.Extension imports = + $pb.Extension('google.protobuf.FileOptions', 'imports', + 28125061, $pb.PbFieldType.OM, + defaultOrMaker: Imports.getDefault, subBuilder: Imports.create); + static final $pb.Extension<$core.String, $core.String> defaultMixin = + $pb.Extension<$core.String, $core.String>('google.protobuf.FileOptions', + 'defaultMixin', 96128839, $pb.PbFieldType.OS); + static final $pb.Extension<$core.String, $core.String> mixin = + $pb.Extension<$core.String, $core.String>( + 'google.protobuf.MessageOptions', + 'mixin', + 96128839, + $pb.PbFieldType.OS); + static final $pb.Extension<$core.bool, $core.bool> overrideGetter = + $pb.Extension<$core.bool, $core.bool>('google.protobuf.FieldOptions', + 'overrideGetter', 28205290, $pb.PbFieldType.OB); + static final $pb.Extension<$core.bool, $core.bool> overrideSetter = + $pb.Extension<$core.bool, $core.bool>('google.protobuf.FieldOptions', + 'overrideSetter', 28937366, $pb.PbFieldType.OB); + static final $pb.Extension<$core.bool, $core.bool> overrideHasMethod = + $pb.Extension<$core.bool, $core.bool>('google.protobuf.FieldOptions', + 'overrideHasMethod', 28937461, $pb.PbFieldType.OB); + static final $pb.Extension<$core.bool, $core.bool> overrideClearMethod = + $pb.Extension<$core.bool, $core.bool>('google.protobuf.FieldOptions', + 'overrideClearMethod', 28907907, $pb.PbFieldType.OB); + static final $pb.Extension<$core.String, $core.String> dartName = + $pb.Extension<$core.String, $core.String>('google.protobuf.FieldOptions', + 'dartName', 28700919, $pb.PbFieldType.OS); static void registerAllExtensions($pb.ExtensionRegistry registry) { registry.add(imports); registry.add(defaultMixin); diff --git a/protoc_plugin/lib/src/descriptor.pb.dart b/protoc_plugin/lib/src/descriptor.pb.dart index cddd9ed47..8efcab926 100644 --- a/protoc_plugin/lib/src/descriptor.pb.dart +++ b/protoc_plugin/lib/src/descriptor.pb.dart @@ -3,7 +3,7 @@ // source: descriptor.proto // // @dart = 2.3 -// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type +// ignore_for_file: camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type import 'dart:core' as $core; diff --git a/protoc_plugin/lib/src/descriptor.pbenum.dart b/protoc_plugin/lib/src/descriptor.pbenum.dart index b31a73369..25fcb0bf8 100644 --- a/protoc_plugin/lib/src/descriptor.pbenum.dart +++ b/protoc_plugin/lib/src/descriptor.pbenum.dart @@ -3,7 +3,7 @@ // source: descriptor.proto // // @dart = 2.3 -// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type +// ignore_for_file: camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type // ignore_for_file: UNDEFINED_SHOWN_NAME,UNUSED_SHOWN_NAME import 'dart:core' as $core; diff --git a/protoc_plugin/lib/src/plugin.pb.dart b/protoc_plugin/lib/src/plugin.pb.dart index 1c5ce4e9f..03315af68 100644 --- a/protoc_plugin/lib/src/plugin.pb.dart +++ b/protoc_plugin/lib/src/plugin.pb.dart @@ -3,7 +3,7 @@ // source: plugin.proto // // @dart = 2.3 -// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type +// ignore_for_file: camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type import 'dart:core' as $core; diff --git a/protoc_plugin/pubspec.yaml b/protoc_plugin/pubspec.yaml index 3e7130266..b23de7cbe 100644 --- a/protoc_plugin/pubspec.yaml +++ b/protoc_plugin/pubspec.yaml @@ -17,3 +17,5 @@ dev_dependencies: executables: protoc-gen-dart: protoc_plugin + +dependency_overrides: {protobuf: {path: ../protobuf}} diff --git a/protoc_plugin/test/repeated_field_test.dart b/protoc_plugin/test/repeated_field_test.dart index ec036cb7a..42cf837e7 100644 --- a/protoc_plugin/test/repeated_field_test.dart +++ b/protoc_plugin/test/repeated_field_test.dart @@ -18,19 +18,19 @@ void main() { var msg = TestAllTypes(); expect( (msg.info_.byName["repeatedNestedMessage"] - as FieldInfo) + as FieldInfo>) .check, isNotNull); expect( (msg.info_.byName["repeatedgroup"] - as FieldInfo) + as FieldInfo>) .check, isNotNull); expect( (msg.info_.byName["repeatedNestedEnum"] - as FieldInfo) + as FieldInfo>) .check, isNotNull); });