golang / protobuf

Go support for Google's protocol buffers
BSD 3-Clause "New" or "Revised" License
9.64k stars 1.58k forks source link

`ProtoReflect().GetUnknown()` Not Working #1618

Open frankgreco opened 1 month ago

frankgreco commented 1 month ago

What version of protobuf and what language are you using? v1.5.4

What did you do?

func TestUnknownFields(t *testing.T) {
    request := new(helloworld.HelloRequest)

    err := (&protojson.UnmarshalOptions{DiscardUnknown: true}).Unmarshal([]byte(
        `{"foo":"bar"}`,
    ), request)

    assert.NoError(t, err)
    assert.Equal(t, 1, len(request.ProtoReflect().GetUnknown()))
}

What did you expect to see? I expected the assertions to pass and there to be one unknown item.

What did you see instead? The last assertion failed. The actual length is 0.

puellanivis commented 1 month ago
// If DiscardUnknown is set, unknown fields and enum name values are ignored.

You’re explicitly telling protojson to discard those unknown values.

frankgreco commented 1 month ago

@puellanivis that field has no impact on the length of request.ProtoReflect().GetUnknown(). I get the same result regardless of the value.

puellanivis commented 1 month ago

This seems related to: https://github.com/golang/protobuf/issues/1390

Right now, there’s no defined way to know the wire format for these unknown JSON fields, so they cannot be rendered into the GetUnknown() response.

neild commented 1 month ago

Unknown fields are only preserved in the binary encoding.

Setting DiscardUnknown tells protojson.Unmarshal to discard unknown fields (as the name says). If you don't set DiscardUnknown, protojson.Unmarshal will return an error if it encounters any field names it does not recognize.