Skip to content

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

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions