Git Product home page Git Product logo

Comments (19)

puellanivis avatar puellanivis commented on August 18, 2024 2

This suggests that the JSON should continue to parse with the reserved field name.

I agree - so that means that protojson doesn't behave according to this, right?

We’ll need more input from contributors, but I think from my reading that this is a misbehavior. I’ve also advised someone based on this guidance that I suspected reserving a field name would be that it would be recognized as known but ignored, not breaking like this.

from protobuf.

lfolger avatar lfolger commented on August 18, 2024 1

Thanks for reporting this. I think this should be fixed.
The behavior is documented in the spec and the go implementation is not following it.
I double checked and the C++ implementation for example follows the spec.

I'll try to prepare a change for this and test is in Google first to see if anyone relies on the old behavior (I don't expect anyone to but you never know).

from protobuf.

lfolger avatar lfolger commented on August 18, 2024 1

Short update. There is still an ongoing discussion internally about what the behavior should be. I will come back to this once I know more.

from protobuf.

puellanivis avatar puellanivis commented on August 18, 2024

At least adding a basic protobuf definition with input that repros would be helpful for understanding.

from protobuf.

timofurrer avatar timofurrer commented on August 18, 2024

@puellanivis I've updated the description.

from protobuf.

puellanivis avatar puellanivis commented on August 18, 2024

Hm, it works if you set protojson.UnmarshalOptions{ DiscardUnknown: true }

I suppose the question is, should reserved field names be discarded as “known”. From the text of https://protobuf.dev/programming-guides/proto3/#fieldreserved:

To make sure JSON and TextFormat instances of your message can still be parsed, also add the deleted field name to a reserved list.

This suggests that the JSON should continue to parse with the reserved field name.

from protobuf.

timofurrer avatar timofurrer commented on August 18, 2024

Yes, I'm aware that I can discard unknown fields, but that would discard "all" unknown fields - which is not what I want.

This suggests that the JSON should continue to parse with the reserved field name.

I agree - so that means that protojson doesn't behave according to this, right?

from protobuf.

timofurrer avatar timofurrer commented on August 18, 2024

We’ll need more input from contributors

@puellanivis anything we (or I) can do to get that "input" ?

from protobuf.

puellanivis avatar puellanivis commented on August 18, 2024

You could work on a gerrit change request yourself. I think the in-house Google devs are otherwise busy with editions support.

from protobuf.

timofurrer avatar timofurrer commented on August 18, 2024

@lfolger that's good news that you'll have a look at this - it's highly appreciated, thank you 🤝

from protobuf.

lfolger avatar lfolger commented on August 18, 2024

While looking into this I found out that this is already the behavior today. Could you clarify the steps to reproduce?

These are the tests that I added and they succeeded without errors: https://go-review.googlesource.com/c/protobuf/+/581095

from protobuf.

lfolger avatar lfolger commented on August 18, 2024

I just realized this is about protojson. Let me try to add a test for that as well.

from protobuf.

lfolger avatar lfolger commented on August 18, 2024

Unfortunately, the C++ implementation has the same issue. Usually the C++ implementation is right and diverging from it means in most cases diverging from the spec. I reached out to the core protobuf team to clarify. I'll report back once I know more.

Sorry for the back and forth.

from protobuf.

lfolger avatar lfolger commented on August 18, 2024

AFter discussion it turned out that the current behavior is a "bug" in the Text proto parser and intended behavior in the JSON format. I call this "bug" because the implementation is more permissive that it has to be which most users don't mind.

A documentation update to the official documentation will follow shortly.

If you like the behavior to be changed, you would need to file a feature request against the protobuf.

Just to manage expexctations, I'm not very hopeful that they will accept this but you should give it a try nonetheless. Maybe there will be enough users and use cases that need this and they will accept it. If that happens, we are happy to add this to the Go implementation.

I'm closing this issue for now but feel free to reopen it if you have more questions.

from protobuf.

ash2k avatar ash2k commented on August 18, 2024

Hi all! I've been following this issue. I don't think this has been mentioned, I'd like to point out an inconsistency between binary proto unmarshaling and JSON->proto message unmarshling. Reserved fields are ignored in the binary format and you don't get an error. I think this makes sense. I wonder why is it not the same for any other format that can be unmarshaled into a proto message?

If it is how it is and the behavior is not going to change, then:

  • what is the suggested approach to read the previously written JSON messages when a field has been removed?
  • "Text proto parser has a bug" - perhaps this issue can be used to fix it.
  • https://protobuf.dev/programming-guides/proto3/#fieldreserved needs to be updated to state that the user will get an error. This means we are changing the spec because of how implementations behave (not the other way around) 🤔

from protobuf.

ash2k avatar ash2k commented on August 18, 2024

Yet another way to think about it: currently reserved is a no-op for JSON unmarshaling. To me it is a signal that something is not right - either the spec defines something useless (if we forget about the binary format, with which JSON is not consistent) or the implementation doesn't follow the spec.

p.s. Would be great to hear some of the counter-arguments from the internal discussion. To be honest, it's a bit annoying that this is being discussed behind closed doors. There are lots and lots of users of the format and libraries and there is an open issue tracker and this project is open source in the first place. Why all that if not for transparency and collaboration? So, I'm sure a bit more transparency would be greatly appreciated by the community. Thank you.

from protobuf.

puellanivis avatar puellanivis commented on August 18, 2024

The semantics of it has pretty much always been documentation of fields to not re-use because they’ve been removed. I believe it is an error during the compilation if a field attempts to reuse either a field number or field name, so it is not strictly a fully no-op.

from protobuf.

timofurrer avatar timofurrer commented on August 18, 2024

The spec literally mentions that reserved can be used so that JSON can still be parsed (from last sentence in second paragraph here):

If you update a message type by entirely deleting a field, or commenting it out, future developers can reuse the field number when making their own updates to the type. This can cause severe issues, as described in Consequences of Reusing Field Numbers.

To make sure this doesn’t happen, add your deleted field number to the reserved list. To make sure JSON and TextFormat instances of your message can still be parsed, also add the deleted field name to a reserved list.

I agree with @ash2k here that it's kinda frustrating to fix a bug by changing the spec.

Assuming there is NO way that this gets fixed (which would be really sad), would you be open to add an opt-in config to the json marshaller to enable this behavior? .. and make json parsing align to the behavior to binary parsing?

from protobuf.

lfolger avatar lfolger commented on August 18, 2024

"Text proto parser has a bug" - perhaps this issue can be used to fix it

First of all, when I said the Go implementation has a bug in the text parser, I meant that it accepts messages with unkown but reserved fields. To be clear only C++ and Go do this. All other implementation we know don't do this. This means JSON and text parsers behave the same (except for C++/Go).

Would be great to hear some of the counter-arguments from the internal discussion. To be honest, it's a bit annoying that this is being discussed behind closed doors.

About the discussion not being public, I was not even part of that discussion. I think if you want a public discussion, you need to file a feature request against the protobuf main repository which handles changes to the spec. It was partially me fault in that I reached out to them internally rather than just asking you to file a bug against the proto repo directly. Sorry about that.

I'd like to point out an inconsistency between binary proto unmarshaling and JSON->proto message unmarshling. Reserved fields are ignored in the binary format and you don't get an error

The accepting of unknown field in the binary format works very different. It accepts all unknown fields. It is completely independent of the reserved fields. You can get the same behavior by using the appropriate unmarshaloptions for protojson and prototext.

Again, there is no point in discussion this here. We, the Go protobuf maintainers, are not responsible for the spec. If you would like to see the spec changed, file a feature request against the proto buf repository. All we can do is to follow the spec.

from protobuf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.