Description
In our project, given the FileName
message with the following structure:
message FileName {
option (is).java_type = "app.purephotos.fs.FileNameMixin";
// The name of the file
string name = 1 [(required) = true];
// An optional file extension.
Extension extension = 2;
}
And the generated method that parses a plain JS object, which comes from the backend, to the FileName
message:
// Generated by Spine ProtoJs Plugin
// ...
proto.purephotos.fs.FileName.Parser.prototype.fromObject = function(obj) {
if (obj === null) {
return null;
}
let msg = new proto.purephotos.fs.FileName();
if (obj.name !== undefined) {
if (obj.name !== null) {
let value = obj.name;
msg.setName(value);
}
}
if (obj.extension !== undefined) {
if (obj.extension !== null) {
let value = proto.purephotos.fs.Extension[obj.extension];
msg.setExtension(value); // but not `setExtension$(value)
}
}
return msg;
};
The parser uses the wrong setter method for the extension
field. As I know, the "extension" is a private keyword of the Protobuf message. So if a custom message contains the "extension" field, the JS compiler adds a dollar sign ($) to the end of names of such getters and setters, like setExtension$
. So, we use these getters and setters to access or change "our" extension
fields. But in this case, the generated code references the wrong field.
As a quick fix, we override the FileName.Parser
on our side and basically use the same code but with the correct setter:
const backend = init({
protoIndexFiles: [
fixedParsers, // contains fixed `FileName.Parser`
webProtobufs,
purePhotosProtobufs,
],
forCommands: directBackendOptions,
forQueries: directBackendOptions,
forSubscriptions: firebaseBackendOptions,
});
The issue is to take into account the "extension" field name and other possible private field names when generating parsers for JS messages.
Our environment:
node: v18.15.0
npm: 9.5.0
Spine base version: 1.8.2
spine-web
: 1.7.4