Skip to content

Use of setters for fields with certain names in generated JS parsers #787

Open
@YehorPytomets

Description

@YehorPytomets

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions