Skip to content

Commit

Permalink
Initial support for legacy groups + test case, see #568
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodeIO committed Dec 18, 2016
1 parent f8451f0 commit 974a132
Show file tree
Hide file tree
Showing 27 changed files with 541 additions and 282 deletions.
377 changes: 235 additions & 142 deletions dist/protobuf.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/protobuf.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/protobuf.min.js

Large diffs are not rendered by default.

Binary file modified dist/protobuf.min.js.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion dist/protobuf.min.js.map

Large diffs are not rendered by default.

70 changes: 35 additions & 35 deletions dist/runtime/protobuf.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/runtime/protobuf.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/runtime/protobuf.min.js

Large diffs are not rendered by default.

Binary file modified dist/runtime/protobuf.min.js.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion dist/runtime/protobuf.min.js.map

Large diffs are not rendered by default.

37 changes: 28 additions & 9 deletions src/decode.js
Expand Up @@ -22,8 +22,13 @@ function decode(readerOrBuffer, length) {
message = new (this.getCtor())();
while (reader.pos < limit) {
var tag = reader.uint32(),
wireType = tag & 7,
field = fields[tag >>> 3].resolve(),
wireType = tag & 7;

// End group
if (wireType === 4)
break;

var field = fields[tag >>> 3].resolve(),
type = field.resolvedType instanceof Enum ? "uint32" : field.type;

// Known fields
Expand Down Expand Up @@ -56,13 +61,13 @@ function decode(readerOrBuffer, length) {

// Non-packed
} else if (types.basic[type] === undefined)
values.push(field.resolvedType.decode(reader, reader.uint32()));
values.push(field.resolvedType.decode(reader, field.resolvedType.group ? undefined : reader.uint32()));
else
values.push(reader[type]());

// Non-repeated
} else if (types.basic[type] === undefined)
message[field.name] = field.resolvedType.decode(reader, reader.uint32());
message[field.name] = field.resolvedType.decode(reader, field.resolvedType.group ? undefined : reader.uint32());
else
message[field.name] = reader[type]();

Expand Down Expand Up @@ -90,7 +95,11 @@ decode.generate = function generate(mtype) {
("r instanceof Reader||(r=Reader.create(r))")
("var c=l===undefined?r.len:r.pos+l,m=new(this.getCtor())")
("while(r.pos<c){")
("var t=r.int32()")
("var t=r.int32()");
if (mtype.group) gen
("if((t&7)===4)")
("break");
gen
("switch(t>>>3){");

for (var i = 0; i < fields.length; ++i) {
Expand All @@ -100,6 +109,7 @@ decode.generate = function generate(mtype) {
gen
("case %d:", field.id);

// Map fields
if (field.map) {

var keyType = field.resolvedKeyType /* only valid is enum */ ? "uint32" : field.keyType;
Expand All @@ -116,27 +126,36 @@ decode.generate = function generate(mtype) {
else gen
("m%s[k]=r.%s()", prop, type);

// Repeated fields
} else if (field.repeated) { gen

("m%s&&m%s.length?m%s:m%s=[]", prop, prop, prop, prop);

// Packed
if (field.packed && types.packed[type] !== undefined) gen
("if((t&7)===2){")
("var e=r.uint32()+r.pos")
("while(r.pos<e)")
("m%s.push(r.%s())", prop, type)
("}else");
if (types.basic[type] === undefined) gen
("m%s.push(types[%d].decode(r,r.uint32()))", prop, i, i);

// Non-packed
if (types.basic[type] === undefined) gen(field.resolvedType.group
? "m%s.push(types[%d].decode(r))"
: "m%s.push(types[%d].decode(r,r.uint32()))", prop, i);
else gen
("m%s.push(r.%s())", prop, type);

} else if (types.basic[type] === undefined) gen
("m%s=types[%d].decode(r,r.uint32())", prop, i, i);
// Non-repeated
} else if (types.basic[type] === undefined) gen(field.resolvedType.group
? "m%s=types[%d].decode(r)"
: "m%s=types[%d].decode(r,r.uint32())", prop, i);
else gen
("m%s=r.%s()", prop, type);
gen
("break");

// Unknown fields
} return gen
("default:")
("r.skipType(t&7)")
Expand Down
61 changes: 30 additions & 31 deletions src/encode.js
Expand Up @@ -7,6 +7,15 @@ var Enum = require("./enum"),
util = require("./util");
var safeProp = util.safeProp;

function encodeType(field, value, writer) {
if (field.resolvedType.group)
field.resolvedType.encode(value, writer.uint32((field.id << 3 | 3) >>> 0)).uint32((field.id << 3 | 4) >>> 0);
else if (field.resolvedType.encode(value, writer.fork()).len || field.required)
writer.ldelim(field.id);
else
writer.reset();
}

/**
* General purpose message encoder.
* @param {Message|Object} message Runtime message or plain object to encode
Expand Down Expand Up @@ -58,12 +67,12 @@ function encode(message, writer) {
// Non-packed
} else {
var i = 0;
if (wireType !== undefined)
if (wireType === undefined)
while (i < values.length)
writer.uint32((field.id << 3 | wireType) >>> 0)[type](values[i++]);
encodeType(field, values[i++], writer);
else
while (i < values.length)
field.resolvedType.encode(values[i++], writer.uint32((field.id << 3 | 2) >>> 0).fork()).ldelim();
writer.uint32((field.id << 3 | wireType) >>> 0)[type](values[i++]);
}

}
Expand All @@ -76,22 +85,25 @@ function encode(message, writer) {
||
(field.required || value !== undefined) && (field.long ? util.longNe(value, field.defaultValue.low, field.defaultValue.high) : value !== field.defaultValue)
) {
if (wireType !== undefined)
if (wireType === undefined)
encodeType(field, value, writer);
else
writer.uint32((field.id << 3 | wireType) >>> 0)[type](value);
else {
field.resolvedType.encode(value, writer.fork());
if (writer.len || field.required)
writer.ldelim(field.id);
else
writer.reset();
}
}
}
}
return writer;
/* eslint-enable block-scoped-var, no-redeclare */
}

function genEncodeType(gen, field, fieldIndex, ref, alwaysRequired) {
if (field.resolvedType.group)
return gen("types[%d].encode(%s,w.uint32(%d)).uint32(%d)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0);
return alwaysRequired || field.required
? gen("types[%d].encode(%s,w.uint32(%d).fork()).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0)
: gen("types[%d].encode(%s,w.fork()).len&&w.ldelim(%d)||w.reset()", fieldIndex, ref, field.id);
}

/**
* Generates an {@link Encoder|encoder} specific to the specified message type.
* @typedef GenerateEncoder
Expand Down Expand Up @@ -122,7 +134,7 @@ encode.generate = function generate(mtype) {
("for(var ks=Object.keys(m%s),i=0;i<ks.length;++i){", prop)
("w.uint32(%d).fork().uint32(%d).%s(ks[i])", (field.id << 3 | 2) >>> 0, 8 | types.mapKey[keyType], keyType);
if (wireType === undefined) gen
("types[%d].encode(m%s[ks[i]],w.uint32(18).fork()).ldelim()", i, prop);
("types[%d].encode(m%s[ks[i]],w.uint32(18).fork()).ldelim()", i, prop); // can't be groups
else gen
("w.uint32(%d).%s(m%s[ks[i]])", 16 | wireType, type, prop);
gen
Expand Down Expand Up @@ -150,8 +162,8 @@ encode.generate = function generate(mtype) {
("for(var i=0;i<m%s.length;++i)", prop);
if (wireType !== undefined) gen
("w.uint32(%d).%s(m%s[i])", (field.id << 3 | wireType) >>> 0, type, prop);
else gen
("types[%d].encode(m%s[i],w.uint32(%d).fork()).ldelim()", i, prop, (field.id << 3 | 2) >>> 0);
else
genEncodeType(gen, field, i, "m" + prop + "[i]", true);

}

Expand All @@ -168,17 +180,10 @@ encode.generate = function generate(mtype) {
}

if (wireType !== undefined) gen

("w.uint32(%d).%s(m%s)", (field.id << 3 | wireType) >>> 0, type, prop);
else
genEncodeType(gen, field, i, "m" + prop);

else if (field.required) gen

("types[%d].encode(m%s,w.uint32(%d).fork()).ldelim()", i, prop, (field.id << 3 | 2) >>> 0);

else gen

("types[%d].encode(m%s,w.fork()).len&&w.ldelim(%d)||w.reset()", i, prop, field.id);

}
}
for (var i = 0; i < oneofs.length; ++i) {
Expand All @@ -196,16 +201,10 @@ encode.generate = function generate(mtype) {
("case%j:", field.name);

if (wireType !== undefined) gen

("w.uint32(%d).%s(m%s)", (field.id << 3 | wireType) >>> 0, type, prop);
else
genEncodeType(gen, field, fields.indexOf(field), "m" + prop);

else if (field.required) gen

("types[%d].encode(m%s,w.uint32(%d).fork()).ldelim()", fields.indexOf(field), prop, (field.id << 3 | 2) >>> 0);

else gen

("types[%d].encode(m%s,w.fork()).len&&w.ldelim(%d)||w.reset()", fields.indexOf(field), prop, field.id);
gen
("break;");

Expand Down
4 changes: 2 additions & 2 deletions src/enum.js
@@ -1,12 +1,12 @@
"use strict";
module.exports = Enum;

Enum.className = "Enum";

var ReflectionObject = require("./object");
/** @alias Enum.prototype */
var EnumPrototype = ReflectionObject.extend(Enum);

Enum.className = "Enum";

var util = require("./util");

var _TypeError = util._TypeError;
Expand Down
8 changes: 4 additions & 4 deletions src/field.js
@@ -1,14 +1,14 @@
"use strict";
module.exports = Field;

Field.className = "Field";

var ReflectionObject = require("./object");
var Message = require("./message");
/** @alias Field.prototype */
var FieldPrototype = ReflectionObject.extend(Field);

var Enum = require("./enum"),
Field.className = "Field";

var Message = require("./message"),
Enum = require("./enum"),
types = require("./types"),
util = require("./util");

Expand Down

0 comments on commit 974a132

Please sign in to comment.