protobufjs / protobuf.js

Protocol Buffers for JavaScript & TypeScript.
Other
9.77k stars 1.4k forks source link

pbjs generates a syntax error with es6 javascript #1452

Open noveyak opened 4 years ago

noveyak commented 4 years ago

protobuf.js version: 6.10.1

Expected behavior

pbjs should generate javascript free of syntax errors when using wrap = es6

Actual behavior

If there are 2 map fields in a protobuf message, pbjs generates code that redeclares let which is a SyntaxError. This did not happen in version 6.9.0

Code

pbjs -t static-module -w es6 ./message.proto
message Test {
  map<string, string> map_1 = 1;
  map<string, string> map_2 = 2;
}

Resulting javascript - end2 is declared twice, in case 1 and case 2 but the case statements are not wrapped in brackets

    Test.decode = function decode(reader, length) {
        if (!(reader instanceof $Reader))
            reader = $Reader.create(reader);
        let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Test(), key, value;
        while (reader.pos < end) {
            let tag = reader.uint32();
            switch (tag >>> 3) {
            case 1:
                if (message.map_1 === $util.emptyObject)
                    message.map_1 = {};
                let end2 = reader.uint32() + reader.pos;
                key = "";
                value = "";
                while (reader.pos < end2) {
                    let tag2 = reader.uint32();
                    switch (tag2 >>> 3) {
                    case 1:
                        key = reader.string();
                        break;
                    case 2:
                        value = reader.string();
                        break;
                    default:
                        reader.skipType(tag2 & 7);
                        break;
                    }
                }
                message.map_1[key] = value;
                break;
            case 2:
                if (message.map_2 === $util.emptyObject)
                    message.map_2 = {};
                let end2 = reader.uint32() + reader.pos;
                key = "";
                value = "";
                while (reader.pos < end2) {
                    let tag2 = reader.uint32();
                    switch (tag2 >>> 3) {
                    case 1:
                        key = reader.string();
                        break;
                    case 2:
                        value = reader.string();
                        break;
                    default:
                        reader.skipType(tag2 & 7);
                        break;
                    }
                }
                message.map_2[key] = value;
                break;
            default:
                reader.skipType(tag & 7);
                break;
            }
        }
        return message;
    };

Javascript using protobufjs 6.9.0

    Test.decode = function decode(reader, length) {
        if (!(reader instanceof $Reader))
            reader = $Reader.create(reader);
        let end = length === undefined ? reader.len : reader.pos + length, message = new $root.Test(), key;
        while (reader.pos < end) {
            let tag = reader.uint32();
            switch (tag >>> 3) {
            case 1:
                reader.skip().pos++;
                if (message.map_1 === $util.emptyObject)
                    message.map_1 = {};
                key = reader.string();
                reader.pos++;
                message.map_1[key] = reader.string();
                break;
            case 2:
                reader.skip().pos++;
                if (message.map_2 === $util.emptyObject)
                    message.map_2 = {};
                key = reader.string();
                reader.pos++;
                message.map_2[key] = reader.string();
                break;
            default:
                reader.skipType(tag & 7);
                break;
            }
        }
        return message;
    };
AndiDog commented 4 years ago

I have also reproduced this, here's a minimal example: https://github.com/AndiDog/protobufjs-identifier-already-declared

elrob commented 3 years ago

I've also hit this issue and had to switch to 6.9.0 to resolve.

dbrgn commented 1 year ago

Note: If you make use of protobuf3 optional fields, downgrading to 6.9 is not an option, because support was only added in 6.11.