diff --git a/protobuf/CHANGELOG.md b/protobuf/CHANGELOG.md index 6b2d55b6..7cf13e1f 100644 --- a/protobuf/CHANGELOG.md +++ b/protobuf/CHANGELOG.md @@ -1,3 +1,5 @@ +## 5.0.0-wip + ## 4.2.0 * Internal refactoring to split the package into libraries. This allows @@ -11,6 +13,9 @@ * Improve performance of `GeneratedMessage` members: `writeToJsonMap`, `writeToJson`, `mergeFromJson`, `mergeFromJsonMap`. ([#1028]) +* Remove `BuilderInfo.fromProto3Json` and `BuilderInfo.toProto3Json` as a part + of an internal refactoring. + [#1026]: https://github.com/google/protobuf.dart/pull/1026 [#1027]: https://github.com/google/protobuf.dart/pull/1027 [#1028]: https://github.com/google/protobuf.dart/pull/1028 diff --git a/protobuf/lib/protobuf.dart b/protobuf/lib/protobuf.dart index d1e569bd..67bfad99 100644 --- a/protobuf/lib/protobuf.dart +++ b/protobuf/lib/protobuf.dart @@ -18,4 +18,6 @@ export 'src/protobuf/internal.dart' GeneratedMessageInternalExtension, MapFieldInfoInternalExtension, mapKeyFieldNumber, - mapValueFieldNumber; + mapValueFieldNumber, + mergeFromProto3JsonAny, + writeToProto3JsonAny; diff --git a/protobuf/lib/src/protobuf/builder_info.dart b/protobuf/lib/src/protobuf/builder_info.dart index d21b3dfa..d98858f3 100644 --- a/protobuf/lib/src/protobuf/builder_info.dart +++ b/protobuf/lib/src/protobuf/builder_info.dart @@ -42,24 +42,17 @@ class BuilderInfo { List? _sortedByTag; // For well-known types. - final Object? Function(GeneratedMessage message, TypeRegistry typeRegistry)? - toProto3Json; - final Function( - GeneratedMessage targetMessage, - Object json, - TypeRegistry typeRegistry, - JsonParsingContext context, - )? - fromProto3Json; + final WellKnownType? _wellKnownType; + final CreateBuilderFunc? createEmptyInstance; BuilderInfo( String? messageName, { PackageName package = const PackageName(''), this.createEmptyInstance, - this.toProto3Json, - this.fromProto3Json, - }) : qualifiedMessageName = '${package.prefix}$messageName'; + WellKnownType? wellKnownType, + }) : qualifiedMessageName = '${package.prefix}$messageName', + _wellKnownType = wellKnownType; void add( int tagNumber, diff --git a/protobuf/lib/src/protobuf/internal.dart b/protobuf/lib/src/protobuf/internal.dart index e3a29d07..95d491ef 100644 --- a/protobuf/lib/src/protobuf/internal.dart +++ b/protobuf/lib/src/protobuf/internal.dart @@ -18,6 +18,7 @@ import 'package:meta/meta.dart' show UseResult; import 'consts.dart'; import 'json/json.dart' as json_lib; import 'json_parsing_context.dart'; +import 'mixins/well_known.dart'; import 'permissive_compare.dart'; import 'type_registry.dart'; import 'utils.dart'; diff --git a/protobuf/lib/src/protobuf/mixins/well_known.dart b/protobuf/lib/src/protobuf/mixins/well_known.dart index 644d92a0..bf63a434 100644 --- a/protobuf/lib/src/protobuf/mixins/well_known.dart +++ b/protobuf/lib/src/protobuf/mixins/well_known.dart @@ -6,9 +6,30 @@ import 'dart:convert'; import 'package:fixnum/fixnum.dart'; -import '../../../protobuf.dart'; +import '../internal.dart'; import '../json_parsing_context.dart'; +/// The set of well known protobuf message types which may have customized +/// serialization logic. +enum WellKnownType { + any, + timestamp, + duration, + struct, + value, + listValue, + fieldMask, + doubleValue, + floatValue, + int64Value, + uint64Value, + int32Value, + uint32Value, + boolValue, + stringValue, + bytesValue, +} + mixin AnyMixin implements GeneratedMessage { String get typeUrl; set typeUrl(String value); @@ -98,14 +119,7 @@ mixin AnyMixin implements GeneratedMessage { ); } final unpacked = info.createEmptyInstance!()..mergeFromBuffer(any.value); - final proto3Json = unpacked.toProto3Json(typeRegistry: typeRegistry); - if (info.toProto3Json == null) { - final map = proto3Json as Map; - map['@type'] = any.typeUrl; - return map; - } else { - return {'@type': any.typeUrl, 'value': proto3Json}; - } + return writeToProto3JsonAny(unpacked.fieldSet, any.typeUrl, typeRegistry); } static void fromProto3JsonHelper( @@ -133,21 +147,13 @@ mixin AnyMixin implements GeneratedMessage { ); } - final Object? subJson = - info.fromProto3Json == null - // TODO(sigurdm): avoid cloning [object] here. - ? (Map.from(object)..remove('@type')) - : object['value']; - // TODO(sigurdm): We lose [context.path]. - final packedMessage = - info.createEmptyInstance!()..mergeFromProto3Json( - subJson, - typeRegistry: typeRegistry, - supportNamesWithUnderscores: context.supportNamesWithUnderscores, - ignoreUnknownFields: context.ignoreUnknownFields, - permissiveEnums: context.permissiveEnums, - ); - + final packedMessage = info.createEmptyInstance!(); + mergeFromProto3JsonAny( + json, + packedMessage.fieldSet, + typeRegistry, + context, + ); any.value = packedMessage.writeToBuffer(); any.typeUrl = typeUrl; } else { diff --git a/protobuf/lib/src/protobuf/proto3_json.dart b/protobuf/lib/src/protobuf/proto3_json.dart index 0fe4849c..de0c2428 100644 --- a/protobuf/lib/src/protobuf/proto3_json.dart +++ b/protobuf/lib/src/protobuf/proto3_json.dart @@ -4,6 +4,40 @@ part of 'internal.dart'; +// Public because this is called from the mixins library. +Object writeToProto3JsonAny( + FieldSet fs, + String typeUrl, + TypeRegistry typeRegistry, +) { + final result = _writeToProto3Json(fs, typeRegistry); + final wellKnownType = fs._meta._wellKnownType; + if (wellKnownType != null) { + switch (wellKnownType) { + case WellKnownType.any: + case WellKnownType.timestamp: + case WellKnownType.duration: + case WellKnownType.struct: + case WellKnownType.value: + case WellKnownType.listValue: + case WellKnownType.fieldMask: + case WellKnownType.doubleValue: + case WellKnownType.floatValue: + case WellKnownType.int64Value: + case WellKnownType.uint64Value: + case WellKnownType.int32Value: + case WellKnownType.uint32Value: + case WellKnownType.boolValue: + case WellKnownType.stringValue: + case WellKnownType.bytesValue: + return {'@type': typeUrl, 'value': result}; + } + } + + (result as Map)['@type'] = typeUrl; + return result; +} + Object? _writeToProto3Json(FieldSet fs, TypeRegistry typeRegistry) { String? convertToMapKey(dynamic key, int keyType) { final baseType = PbFieldType.baseType(keyType); @@ -86,8 +120,46 @@ Object? _writeToProto3Json(FieldSet fs, TypeRegistry typeRegistry) { } final meta = fs._meta; - if (meta.toProto3Json != null) { - return meta.toProto3Json!(fs._message!, typeRegistry); + final wellKnownType = meta._wellKnownType; + if (wellKnownType != null) { + switch (wellKnownType) { + case WellKnownType.any: + return AnyMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.timestamp: + return TimestampMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.duration: + return DurationMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.struct: + return StructMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.value: + return ValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.listValue: + return ListValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.fieldMask: + return FieldMaskMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.doubleValue: + return DoubleValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.floatValue: + return FloatValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.int64Value: + return Int64ValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.uint64Value: + return UInt64ValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.int32Value: + return Int32ValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.uint32Value: + return UInt32ValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.boolValue: + return BoolValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.stringValue: + return StringValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + case WellKnownType.bytesValue: + return BytesValueMixin.toProto3JsonHelper(fs._message!, typeRegistry); + } + // [WellKnownType] could be used to for messages which have special + // encodings in other codecs. The set of messages which special encodings in + // proto3json is handled here, so we intentionally fall through to the + // default message handling rather than throwing. } final result = {}; @@ -156,6 +228,56 @@ extension _FindFirst on Iterable { } } +// Public because this is called from the mixins library. +void mergeFromProto3JsonAny( + Object? json, + FieldSet fieldSet, + TypeRegistry typeRegistry, + JsonParsingContext context, +) { + if (json is! Map) { + throw context.parseException('Expected JSON object', json); + } + + final wellKnownType = fieldSet._meta._wellKnownType; + if (wellKnownType != null) { + switch (wellKnownType) { + case WellKnownType.any: + case WellKnownType.timestamp: + case WellKnownType.duration: + case WellKnownType.struct: + case WellKnownType.value: + case WellKnownType.listValue: + case WellKnownType.fieldMask: + case WellKnownType.doubleValue: + case WellKnownType.floatValue: + case WellKnownType.int64Value: + case WellKnownType.uint64Value: + case WellKnownType.int32Value: + case WellKnownType.uint32Value: + case WellKnownType.boolValue: + case WellKnownType.stringValue: + case WellKnownType.bytesValue: + final value = json['value']; + return _mergeFromProto3JsonWithContext( + value, + fieldSet, + typeRegistry, + context, + ); + } + } + + // TODO(sigurdm): avoid cloning [object] here. + final withoutType = Map.from(json)..remove('@type'); + return _mergeFromProto3JsonWithContext( + withoutType, + fieldSet, + typeRegistry, + context, + ); +} + /// Merge a JSON object representing a message in proto3 JSON format ([json]) /// to [fieldSet]. void _mergeFromProto3Json( @@ -166,12 +288,23 @@ void _mergeFromProto3Json( bool supportNamesWithUnderscores, bool permissiveEnums, ) { - fieldSet._ensureWritable(); final context = JsonParsingContext( ignoreUnknownFields, supportNamesWithUnderscores, permissiveEnums, ); + return _mergeFromProto3JsonWithContext(json, fieldSet, typeRegistry, context); +} + +/// Merge a JSON object representing a message in proto3 JSON format ([json]) +/// to [fieldSet]. +void _mergeFromProto3JsonWithContext( + Object? json, + FieldSet fieldSet, + TypeRegistry typeRegistry, + JsonParsingContext context, +) { + fieldSet._ensureWritable(); void recursionHelper(Object? json, FieldSet fieldSet) { Object? convertProto3JsonValue(Object value, FieldInfo fieldInfo) { @@ -225,16 +358,16 @@ void _mergeFromProto3Json( if (value is String) { // TODO(sigurdm): Do we want to avoid linear search here? Measure... final result = - permissiveEnums + context.permissiveEnums ? fieldInfo.enumValues!.findFirst( (e) => permissiveCompare(e.name, value), ) : fieldInfo.enumValues!.findFirst((e) => e.name == value); - if ((result != null) || ignoreUnknownFields) return result; + if ((result != null) || context.ignoreUnknownFields) return result; throw context.parseException('Unknown enum value', value); } else if (value is int) { return fieldInfo.valueOf!(value) ?? - (ignoreUnknownFields + (context.ignoreUnknownFields ? null : (throw context.parseException( 'Unknown enum value', @@ -368,99 +501,227 @@ void _mergeFromProto3Json( } final meta = fieldSet._meta; - final wellKnownConverter = meta.fromProto3Json; - if (wellKnownConverter != null) { - wellKnownConverter(fieldSet._message!, json, typeRegistry, context); - } else { - if (json is Map) { - final byName = meta.byName; + final wellKnownType = meta._wellKnownType; + if (wellKnownType != null) { + switch (wellKnownType) { + case WellKnownType.any: + AnyMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.timestamp: + TimestampMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.duration: + DurationMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.struct: + StructMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.value: + ValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.listValue: + ListValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.fieldMask: + FieldMaskMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.doubleValue: + DoubleValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.floatValue: + FloatValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.int64Value: + Int64ValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.uint64Value: + UInt64ValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.int32Value: + Int32ValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.uint32Value: + UInt32ValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.boolValue: + BoolValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.stringValue: + StringValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + case WellKnownType.bytesValue: + BytesValueMixin.fromProto3JsonHelper( + fieldSet._message!, + json, + typeRegistry, + context, + ); + return; + } - json.forEach((key, Object? value) { - if (value == null) { - return; - } - if (key is! String) { - throw context.parseException('Key was not a String', key); - } - context.addMapIndex(key); + // [WellKnownType] could be used to for messages which have special + // encodings in other codecs. The set of messages which special encodings + // in proto3json is handled here, so we intentionally fall through to the + // default message handling rather than throwing. + } - var fieldInfo = byName[key]; - if (fieldInfo == null && supportNamesWithUnderscores) { - // We don't optimize for field names with underscores, instead do a - // linear search for the index. - fieldInfo = byName.values.findFirst( - (FieldInfo info) => info.protoName == key, - ); - } - if (fieldInfo == null) { - if (ignoreUnknownFields) { - return; - } else { - throw context.parseException('Unknown field name \'$key\'', key); - } + if (json is Map) { + final byName = meta.byName; + + json.forEach((key, Object? value) { + if (value == null) { + return; + } + if (key is! String) { + throw context.parseException('Key was not a String', key); + } + context.addMapIndex(key); + + var fieldInfo = byName[key]; + if (fieldInfo == null && context.supportNamesWithUnderscores) { + // We don't optimize for field names with underscores, instead do a + // linear search for the index. + fieldInfo = byName.values.findFirst( + (FieldInfo info) => info.protoName == key, + ); + } + if (fieldInfo == null) { + if (context.ignoreUnknownFields) { + return; + } else { + throw context.parseException('Unknown field name \'$key\'', key); } + } - if (PbFieldType.isMapField(fieldInfo.type)) { - if (value is Map) { - final mapFieldInfo = fieldInfo as MapFieldInfo; - final Map fieldValues = fieldSet._ensureMapField(meta, fieldInfo); - value.forEach((subKey, subValue) { - if (subKey is! String) { - throw context.parseException('Expected a String key', subKey); - } - context.addMapIndex(subKey); - fieldValues[decodeMapKey( - subKey, - mapFieldInfo.keyFieldType, - )] = convertProto3JsonValue( - subValue, - mapFieldInfo.valueFieldInfo, - ); - context.popIndex(); - }); - } else { - throw context.parseException('Expected a map', value); - } - } else if (PbFieldType.isRepeated(fieldInfo.type)) { - if (value is List) { - final values = fieldSet._ensureRepeatedField(meta, fieldInfo); - for (var i = 0; i < value.length; i++) { - final entry = value[i]; - context.addListIndex(i); - values.add(convertProto3JsonValue(entry, fieldInfo)); - context.popIndex(); + if (PbFieldType.isMapField(fieldInfo.type)) { + if (value is Map) { + final mapFieldInfo = fieldInfo as MapFieldInfo; + final Map fieldValues = fieldSet._ensureMapField(meta, fieldInfo); + value.forEach((subKey, subValue) { + if (subKey is! String) { + throw context.parseException('Expected a String key', subKey); } - } else { - throw context.parseException('Expected a list', value); - } - } else if (PbFieldType.isGroupOrMessage(fieldInfo.type)) { - // TODO(sigurdm) consider a cleaner separation between parsing and - // merging. - final parsedSubMessage = - convertProto3JsonValue(value, fieldInfo) as GeneratedMessage; - final GeneratedMessage? original = - fieldSet._values[fieldInfo.index!]; - if (original == null) { - fieldSet._setNonExtensionFieldUnchecked( - meta, - fieldInfo, - parsedSubMessage, - ); - } else { - original.mergeFromMessage(parsedSubMessage); + context.addMapIndex(subKey); + fieldValues[decodeMapKey(subKey, mapFieldInfo.keyFieldType)] = + convertProto3JsonValue(subValue, mapFieldInfo.valueFieldInfo); + context.popIndex(); + }); + } else { + throw context.parseException('Expected a map', value); + } + } else if (PbFieldType.isRepeated(fieldInfo.type)) { + if (value is List) { + final values = fieldSet._ensureRepeatedField(meta, fieldInfo); + for (var i = 0; i < value.length; i++) { + final entry = value[i]; + context.addListIndex(i); + values.add(convertProto3JsonValue(entry, fieldInfo)); + context.popIndex(); } } else { - fieldSet._setFieldUnchecked( + throw context.parseException('Expected a list', value); + } + } else if (PbFieldType.isGroupOrMessage(fieldInfo.type)) { + // TODO(sigurdm) consider a cleaner separation between parsing and + // merging. + final parsedSubMessage = + convertProto3JsonValue(value, fieldInfo) as GeneratedMessage; + final GeneratedMessage? original = fieldSet._values[fieldInfo.index!]; + if (original == null) { + fieldSet._setNonExtensionFieldUnchecked( meta, fieldInfo, - convertProto3JsonValue(value, fieldInfo), + parsedSubMessage, ); + } else { + original.mergeFromMessage(parsedSubMessage); } - context.popIndex(); - }); - } else { - throw context.parseException('Expected JSON object', json); - } + } else { + fieldSet._setFieldUnchecked( + meta, + fieldInfo, + convertProto3JsonValue(value, fieldInfo), + ); + } + context.popIndex(); + }); + } else { + throw context.parseException('Expected JSON object', json); } } diff --git a/protobuf/pubspec.yaml b/protobuf/pubspec.yaml index dcce0fed..162dadcc 100644 --- a/protobuf/pubspec.yaml +++ b/protobuf/pubspec.yaml @@ -1,5 +1,5 @@ name: protobuf -version: 4.2.0 +version: 5.0.0 description: >- Runtime library for protocol buffers support. Use with package:protoc_plugin to generate Dart code for your '.proto' files. diff --git a/protoc_plugin/CHANGELOG.md b/protoc_plugin/CHANGELOG.md index b12de704..bf34074d 100644 --- a/protoc_plugin/CHANGELOG.md +++ b/protoc_plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 23.0.0 + +* Update generated code for protobuf 5.0.0. + ## 22.5.0 * Generated files are now formatted using the Dart formatter. The code is @@ -42,30 +46,30 @@ We now parse and generate code cooresponding to the proto options `google.api.default_host` and `google.api.oauth_scopes`: - + ```proto service Firestore { option (google.api.default_host) = "firestore.googleapis.com"; option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform," "https://www.googleapis.com/auth/datastore"; - + ... ``` - + Will generate as: - + ```dart class FirestoreClient extends $grpc.Client { /// The hostname for this service. static const $core.String defaultHost = 'firestore.googleapis.com'; - + /// OAuth scopes needed for the client. static const $core.List<$core.String> oauthScopes = [ 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/datastore', ]; - + ... ``` * Minimum SDK dependency bumped from 3.3.0 to 3.6.0. ([#1001]) diff --git a/protoc_plugin/lib/mixins.dart b/protoc_plugin/lib/mixins.dart index 6d969158..73eb2ff4 100644 --- a/protoc_plugin/lib/mixins.dart +++ b/protoc_plugin/lib/mixins.dart @@ -38,9 +38,11 @@ class PbMixin { /// Typically used for static helpers since you cannot mix in static members. final List? injectedHelpers; - /// Whether the mixin should have static methods for converting to and from - /// proto3 Json. - final bool hasProto3JsonHelpers; + /// The well known type name. + /// + /// Values should match enumerations in the `WellKnownType` enum from + /// `package:protobuf`. + final String? wellKnownType; const PbMixin( this.name, { @@ -48,7 +50,7 @@ class PbMixin { this.parent, this.reservedNames, this.injectedHelpers, - this.hasProto3JsonHelpers = false, + this.wellKnownType, }); /// Returns the mixin and its ancestors, in the order they should be applied. diff --git a/protoc_plugin/lib/src/gen/google/protobuf/duration.pb.dart b/protoc_plugin/lib/src/gen/google/protobuf/duration.pb.dart index 5cba2308..a60ed95b 100644 --- a/protoc_plugin/lib/src/gen/google/protobuf/duration.pb.dart +++ b/protoc_plugin/lib/src/gen/google/protobuf/duration.pb.dart @@ -102,8 +102,7 @@ class Duration extends $pb.GeneratedMessage with $mixin.DurationMixin { package: const $pb.PackageName(_omitMessageNames ? '' : 'google.protobuf'), createEmptyInstance: create, - toProto3Json: $mixin.DurationMixin.toProto3JsonHelper, - fromProto3Json: $mixin.DurationMixin.fromProto3JsonHelper) + wellKnownType: $mixin.WellKnownType.duration) ..aInt64(1, _omitFieldNames ? '' : 'seconds') ..a<$core.int>(2, _omitFieldNames ? '' : 'nanos', $pb.PbFieldType.O3) ..hasRequiredFields = false; diff --git a/protoc_plugin/lib/src/message_generator.dart b/protoc_plugin/lib/src/message_generator.dart index f301ea2f..d3fb0ebb 100644 --- a/protoc_plugin/lib/src/message_generator.dart +++ b/protoc_plugin/lib/src/message_generator.dart @@ -356,9 +356,8 @@ class MessageGenerator extends ProtobufContainer { final packageClause = package == '' ? '' : ', package: $conditionalPackageName'; final proto3JsonClause = - (mixin?.hasProto3JsonHelpers ?? false) - ? ', toProto3Json: $mixinImportPrefix.${mixin!.name}.toProto3JsonHelper, ' - 'fromProto3Json: $mixinImportPrefix.${mixin!.name}.fromProto3JsonHelper' + (mixin?.wellKnownType != null) + ? ', wellKnownType: $mixinImportPrefix.WellKnownType.${mixin!.wellKnownType}' : ''; final String extendedClass; diff --git a/protoc_plugin/lib/src/well_known_types.dart b/protoc_plugin/lib/src/well_known_types.dart index 3b322239..3d93d45e 100644 --- a/protoc_plugin/lib/src/well_known_types.dart +++ b/protoc_plugin/lib/src/well_known_types.dart @@ -28,7 +28,7 @@ static Any pack($protobufImportPrefix.GeneratedMessage message, return result; }''', ], - hasProto3JsonHelpers: true, + wellKnownType: 'any', ), 'google.protobuf.Timestamp': PbMixin( 'TimestampMixin', @@ -44,7 +44,7 @@ static Timestamp fromDateTime($coreImportPrefix.DateTime dateTime) { return result; }''', ], - hasProto3JsonHelpers: true, + wellKnownType: 'timestamp', ), 'google.protobuf.Duration': PbMixin( 'DurationMixin', @@ -67,71 +67,71 @@ static Duration fromDart($coreImportPrefix.Duration duration) => Duration() ..nanos = (duration.inMicroseconds % $coreImportPrefix.Duration.microsecondsPerSecond) * 1000; ''', ], - hasProto3JsonHelpers: true, + wellKnownType: 'duration', ), 'google.protobuf.Struct': PbMixin( 'StructMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'struct', ), 'google.protobuf.Value': PbMixin( 'ValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'value', ), 'google.protobuf.ListValue': PbMixin( 'ListValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'listValue', ), 'google.protobuf.DoubleValue': PbMixin( 'DoubleValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'doubleValue', ), 'google.protobuf.FloatValue': PbMixin( 'FloatValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'floatValue', ), 'google.protobuf.Int64Value': PbMixin( 'Int64ValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'int64Value', ), 'google.protobuf.UInt64Value': PbMixin( 'UInt64ValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'uint64Value', ), 'google.protobuf.Int32Value': PbMixin( 'Int32ValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'int32Value', ), 'google.protobuf.UInt32Value': PbMixin( 'UInt32ValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'uint32Value', ), 'google.protobuf.BoolValue': PbMixin( 'BoolValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'boolValue', ), 'google.protobuf.StringValue': PbMixin( 'StringValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'stringValue', ), 'google.protobuf.BytesValue': PbMixin( 'BytesValueMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'bytesValue', ), 'google.protobuf.FieldMask': PbMixin( 'FieldMaskMixin', importFrom: _wellKnownImportPath, - hasProto3JsonHelpers: true, + wellKnownType: 'fieldMask', ), }; diff --git a/protoc_plugin/pubspec.yaml b/protoc_plugin/pubspec.yaml index 3f6fa260..3a44417c 100644 --- a/protoc_plugin/pubspec.yaml +++ b/protoc_plugin/pubspec.yaml @@ -1,5 +1,5 @@ name: protoc_plugin -version: 22.5.0 +version: 23.0.0 description: A protobuf protoc compiler plugin used to generate Dart code. repository: https://github.com/google/protobuf.dart/tree/master/protoc_plugin @@ -14,7 +14,7 @@ dependencies: dart_style: ^3.0.0 fixnum: ^1.0.0 path: ^1.8.0 - protobuf: ^4.1.0 + protobuf: ^5.0.0 pub_semver: ^2.2.0 dev_dependencies: