Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protobuf is not using correct packed option value when the syntax is set as proto2 #681

Closed
serkangunes opened this issue Feb 20, 2017 · 8 comments
Labels

Comments

@serkangunes
Copy link

protobuf.js version: 6.6.3

Even with the syntax = "proto2" library still packs the repeated enum fields.

TestMessage.proto

syntax = "proto2";

package test;

import "TestMessageFlag.proto";

option java_outer_classname = "TestMessageProto";

message TestMessage {
  repeated test.TestMessageFlag flags = 1;
}

TestMessageFlag.proto

syntax = "proto2";

package test;

enum TestMessageFlag {
  FLAG_1 = 1;
  FLAG_2 = 2;
  FLAG_3 = 3;
  FLAG_4 = 4;
  FLAG_5 = 5;
} 

main node js file.

var protobuf = require("protobufjs");

var proto = require('./TestProtoModule');

protobuf.load("proto/TestMessage.proto", function(err, root) {
    if (err) throw err;

    protobuf.load("proto/TestMessageFlag.proto", function(err2, root2) {
      if (err2) throw err2;

      var TestMessageFlag = root2.lookup("test.TestMessageFlag");
      var TestMessage = root.lookup("test.TestMessage");

      // Create a new message
      var message = TestMessage.create({ flags: [
        TestMessageFlag.values.FLAG_4,
        TestMessageFlag.values.FLAG_2,
        TestMessageFlag.values.FLAG_3,
        TestMessageFlag.values.FLAG_1
      ] });

      // Encode a message
      var buffer = TestMessage.encode(message).finish();
      console.log(buffer)
    });
});

Run the code and it outputs: "<Buffer 0a 04 04 02 03 01>"

Now change the field to be unpacked with an option.

syntax = "proto2";

package test;

import "TestMessageFlag.proto";

option java_outer_classname = "TestMessageProto";

message TestMessage {
  repeated test.TestMessageFlag flags = 1 [packed = false];
}

Now run the same code and it outputs: <Buffer 08 04 08 02 08 03 08 01>
Which is the correct value for unpacked repeated field.

syntax = "proto2" should by default use unpacked without the need for options.

@dcodeIO
Copy link
Member

dcodeIO commented Feb 20, 2017

I wonder how your example is even working with two different root instances.

protobuf.load(["proto/TestMessage.proto", "proto/TestMessageFlag.proto"], function(err, root) {
    ...

@serkangunes
Copy link
Author

I found the issue and submitted a pull request. Can you please review it? Using one root is exactly the same.

#683

@dcodeIO
Copy link
Member

dcodeIO commented Feb 20, 2017

For context: Only repeated enum fields, which also use varint encoding, are affected, because their type is not yet (reliably) known when parsing.

Your PR fixes this by setting packed=X for all kinds of repeated fields, even those (not) using packed encoding. Not quite ideal, will have to think about that. Might be necessary to add a syntax property to message types, so this can be determined properly at runtime.

@dcodeIO dcodeIO added the bug label Feb 20, 2017
@serkangunes
Copy link
Author

The fix only sets the flag when iProto3 is false which means we are using syntax="proto2" therefore if the packed option is undefined the default value should be false. It shouldn't matter if it is an enum or not as far as I know.

@dcodeIO
Copy link
Member

dcodeIO commented Feb 23, 2017

See: #683 (comment)

@serkangunes
Copy link
Author

serkangunes commented Feb 24, 2017

Shall I close this issue now? When is it going to be released to npm?

@dcodeIO
Copy link
Member

dcodeIO commented Feb 28, 2017

It's on npm now as 6.6.4.

@dcodeIO dcodeIO closed this as completed Feb 28, 2017
@serkangunes
Copy link
Author

Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants