google / google/protobuf.dart

Support for EmitDefaults during JSON Serialization via toProto3Json()

Open
#585 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Dart
Stars
572
Forks
196
Avg merge
1h 59m
Merged PRs (30d)
2

Description

The [proto3 spec](https://developers.google.com/protocol-buffers/docs/proto3#json_options) states:
```
A proto3 JSON implementation may provide the following options:

Emit fields with default values: Fields with default values are omitted by default in proto3 JSON output. An implementation may provide an option to override this behavior and output fields with their default values.
```

An example of this for the protoc-gen-go plugin is `EmitDefaults` option:
https://pkg.go.dev/github.com/golang/protobuf/jsonpb#Marshaler

I think it would be great if we could achieve this same functionality via the protoc-gen-dart plugin.

As far as I can tell, this functionality is not currently supported by this plugin. Please confirm if that is the case. If this functionality is not currently supported, I would like to look into adding it, as I think it could be a useful feature for other uses of the plugin as well.

Steps to reproduce:
1. Create a proto file:
```
syntax = "proto3";

message Money {
string currency_code = 1;
int64 units = 2;
int32 nanos = 3;
}
```
2. Run protoc with the `dart_out` option to run the `protoc-gen-dart` plugin
`protoc --dart_out=lib/src/generated -Iprotos protos/money.proto`
3. Construct a message with the `units` field populated:
```
final Money amount = Money.create()
..currencyCode = "USD"
..units = $fixnum.Int64.parseInt("1")
..nanos = 750000000;
var json = jsonEncode(amount.toProto3Json());
print('Serialized JSON: $json\n');
```
4. Observe that the serialized JSON contains this field:
`{"currencyCode":"USD","units":"1","nanos":750000000}`
5. Construct a message without the units field:
```
final Money amount = Money.create()
..currencyCode = "USD"
..nanos = 750000000;
```
6. Observe that the serialized JSON does not contain this field:
`{"currencyCode":"USD","nanos":750000000}`

For our use case, this is problematic, because we'd like to store the serialized JSON into a `jsonb` field in Postgres, and with so many potentially missing fields, they jsonb queries can get very cumbersome.

Again, we're willing to contribute to the project to provide serialization of fields with default values as an option, but want to double check this isn't already available in the plugin, and just hadn't figured out how to do it.

Contributor guide

Open the contributing guide

Research direction

Start at the generated message entry point toProto3Json() and the protoc-gen-dart plugin, using the provided Money reproduction as the baseline. Confirm the current omission of default-valued fields, then define and verify an option that includes them in JSON output while preserving existing behavior by default.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.