protocolbuffers / protocolbuffers/protobuf

protoc should not populate `json_name` in descriptor if no `json_name` was specified

Open
#5,587 40 comments 9 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

json keep open protoc
Dominant language
C++
Stars
72k
Forks
16.3k
Avg merge
1d 17h
Merged PRs (30d)
140

Description

What version of protobuf and what language are you using?
Version: v3.6.0
Language: any

What operating system (Linux, Windows, ...) and version?
n/a

What runtime / compiler are you using (e.g., python version or gcc version)
n/a

What did you do?
Steps to reproduce the behavior:

test.proto:

syntax = "proto3";

package testing;

message Animal {
  string name = 1;
  bool has_hooves = 2;
  int32 birth_year = 3 [json_name = "year_of_birth"];
}

Command:

protoc -o /dev/stdout test.proto | protoc --decode=google.protobuf.FileDescriptorSet descriptor.proto

Output:

file {
  name: "test.proto"
  package: "testing"
  message_type {
    name: "Animal"
    field {
      name: "name"
      number: 1
      label: LABEL_OPTIONAL
      type: TYPE_STRING
      json_name: "name"
    }
    field {
      name: "has_hooves"
      number: 2
      label: LABEL_OPTIONAL
      type: TYPE_BOOL
      json_name: "hasHooves"
    }
    field {
      name: "birth_year"
      number: 3
      label: LABEL_OPTIONAL
      type: TYPE_INT32
      json_name: "year_of_birth"
    }
  }
  syntax: "proto3"
}

What did you expect to see
It should be possible to tell whether json_name was specified in the .proto file. In particular, there should be a way to distinguish that json_name was specified for birth_year, and not specified for has_hooves.

What did you see instead?
It is impossible to tell whether json_name was specified in the .proto file, because protoc invents a json_name for each field, regardless.

Anything else

  1. This makes it impossible to create a json serializer that prefers the vanilla protobuf field names (with underscores, by convention), but lets individual fields be overridden. Instead, the default is the weird java-ish mangled version of field names. I'm fine with that being the default, but other options should be possible. For instance, in Go's jsonpb, there is an OrigName option. But it's all-or-nothing. If you opt out of the java-ish names, you also opt out of being able to override a name.
  2. This bloats the serialized descriptor. The language runtimes can manufacture default json field names just fine.
  3. This makes it less possible to recreate something close to the original .proto file from the descriptor.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the behavior with test.proto and the protoc command shown, decoding the result with descriptor.proto. Trace how protoc builds the FileDescriptorSet and how json_name is represented for fields with and without an explicit option; done means the descriptor preserves that distinction without breaking the explicit birth_year override.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.