Open ehyland opened 2 years ago
A quick change from ↴
syntax = "proto3";
...
to ↴
syntax = "proto2";
...
... should do the trick. The reason that you're getting an error is because the optional
key modifier doesn't exist in proto3 - all values are optional by default. You can either remove the optional modifiers, and stick with proto3
, or just use the proto2
syntax.
That is incorrect. A new optional
modifier was added in proto3
with slightly different semantics than the similar modifier in proto2
. Protobuf.js has support for that modifier, but this seems to be a consequence of the combination of that modifier, custom field options, and descriptor message generation.
Interesting, just taking a look at this
write-up on the changes to field presence behaviors in the v3.15 release - that table outlines the optional
modifier support for the scalar primitives. So, the combination of the optional
modifier with the bool
scalar is more than likely a syntactic error.
Looking at the official docs:
For
string
,bytes
, and message fields,optional
is compatible withrepeated
. Given serialized data of a repeated field as input, clients that expect this field to be optional will take the last input value if it's a primitive type field or merge all input elements if it's a message type field. Note that this is not generally safe for numeric types, including bools and enums. Repeated fields of numeric types can be serialized in the packed format, which will not be parsed correctly when an optional field is expected.
I don't think you're interpreting that correctly either. The table you linked has two entries for "Singular numeric (integer or floating point)", one with optional
and one without, which shows that optional numeric fields are supported.
The other quotation there is about the wire compatibility between message declarations that declare a field as optional
and declarations for the same message type that declare a field as repeated
. It doesn't say anything about the usability of the optional
modifier itself.
Looking at the call stack, starting at parseExtension
:
https://github.com/protobufjs/protobuf.js/blob/f5b893c03e9694bbe7da7c4001cc74b06039eb9c/src/parse.js#L749 ↓ https://github.com/protobufjs/protobuf.js/blob/f5b893c03e9694bbe7da7c4001cc74b06039eb9c/src/parse.js#L396 ↓ https://github.com/protobufjs/protobuf.js/blob/f5b893c03e9694bbe7da7c4001cc74b06039eb9c/src/namespace.js#L218
So it looks like namespace extensions aren't compatible with optional
modifiers whatsoever in proto3
. Did a quick search and it looks like protobufjs/protobuf.js#1602 adds a type guard, but it hasn't landed in a 6.11.x release as of yet.
I don't think you're interpreting that correctly either. The table you linked has two entries for "Singular numeric (integer or floating point)", one with
optional
and one without, which shows that optional numeric fields are supported.
Correct me if I'm wrong but we're talking about a bool
field type in optional bool sensitive = 99999;
, not a singular numeric field type. I haven't looked at the source for optional default value coalescence for bool
scalars but I would imagine it's a noop given the removal of explicit default values in proto3
, and the fact that in a binary value, explicit presence is also a noop (substitution).
The only scenario I could see a where an optional bool
value would make sense is in the case of default: true
.
Don't have a ton of experience with either codebase, so take all of that w/ a grain of salt.
Yes, that is the field I am talking about. bool
is a numeric type. It doesn't match any other entry in that table better, and it is encoded as a varint
, the same as most integer types. It just happens to only have 2 valid values.
The purpose of optional
in proto3 is to add field presence information that otherwise doesn't exist. Essentially, it makes the value nullable. There is no contradiction when using it with bool
, because it effectively adds a third possible value.
That is a good catch with the linked PR. I see that the PR to publish it, protobufjs/protobuf.js#1603, is still pending. I think it is safe to say that fixing this bug is blocked on that release.
👋 hello! Should this be resolved now? i'm hitting this issue (or at least the same stacktrace) in the Retool on-prem container, and unsure if i need to be asking them to upgrade to a more recent version, or if the bug still exists!
There may be multiple causes of very similar stacktraces. Can you file a separate issue with the details of the problem you are experiencing?
Hello, I am also having exactly the same issue as @arussellsaw regarding retool. We are also hitting this issue on retool
the same
When using extend google.protobuf.FieldOptions
I also receive Cannot read properties of undefined
.
The this.parent
is a Namespace
.
It seems like it would be very easy to just catch the undefined and skip it even if the extended fields are left out of the loaded protos.
An easy work around (at least for me) was to remove optional
from my extension.
Can you share a stacktrace of the error you are getting?
TypeError: Cannot read properties of undefined (reading 'indexOf')
at Field.toDescriptor (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:75586:62)
at Root_toDescriptorRecursive (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:75289:66)
at Root_toDescriptorRecursive (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:75291:55)
at Root_toDescriptorRecursive (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:75291:55)
at Root_toDescriptorRecursive (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:75291:55)
at Root.toDescriptor (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:75275:5)
at createPackageDefinition (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:13457:33)
at loadSync (/Users/wsedlacek/Code/work/shipyard/dist/apps/event-sync/main.js:13501:12)
extend google.protobuf.FieldOptions {
optional bool some_value = 50000;
}
This works though.
extend google.protobuf.FieldOptions {
bool some_value = 50000;
}
Problem description
When marking a custom field option as optional,
loadSync
throws a the following errorNote this error only occurs when using
optional
Reproduction steps
npm i
node test-with-optional.js
Environment
v16.13.0
nvm
@grpc/proto-loader@0.6.9
Additional context
Error with stack
Proto file that will fail to load
See https://github.com/ehyland/tmp-proto-loader-issue to reproduce