Skip to content

Commit

Permalink
pbjs proto target field options, language-level compliance with jspb …
Browse files Browse the repository at this point in the history
…test.proto
  • Loading branch information
dcodeIO committed Nov 29, 2016
1 parent 8fdebf8 commit 4affa1b
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 37 deletions.
81 changes: 65 additions & 16 deletions cli/targets/proto.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ var Namespace = protobuf.Namespace,
Field = protobuf.Field,
OneOf = protobuf.OneOf,
Service = protobuf.Service,
Method = protobuf.Method;
Method = protobuf.Method,
types = protobuf.types,
util = protobuf.util;

var out = [];
var indent = 0;
Expand Down Expand Up @@ -61,6 +63,22 @@ function under_score(name) {
.replace(/([A-Z])(?=[a-z]|$)/g, function($0, $1) { return "_" + $1.toLowerCase(); });
}

function escape(str) {
return str.replace(/[\\"']/g, '\\$&')
.replace(/\u0000/g, '\\0');
}

function value(v) {
switch (typeof v) {
case 'boolean':
return v ? 'true' : 'false';
case 'number':
return v.toString();
default:
return '"' + escape(v + '') + '"';
}
}

function buildRoot(root) {
root.resolveAll();
var pkg = [];
Expand Down Expand Up @@ -135,12 +153,18 @@ function buildType(type) {
first = true;
type.fieldsArray.forEach(build);
consolidateExtends(type.nestedArray).remaining.forEach(build);
if (type.extensions && type.extensions.length) {
push("");
type.extensions.forEach(function(range) {
push("extensions " + range[0] + " to " + (range[1] === 0x1FFFFFFF ? "max" : range[1]) + ";");
});
}
--indent;
push("}");
}

function buildField(field, passExtend) {
if (field.partOf || field.declaringType || (field.extend !== undefined && !passExtend))
if (field.partOf || field.declaringField || (field.extend !== undefined && !passExtend))
return;
if (first)
first = false, push("");
Expand All @@ -154,22 +178,46 @@ function buildField(field, passExtend) {
else
sb.push(field.type);
sb.push(under_score(field.name), "=", field.id);
var opts = [];
if (field.repeated) {
if (syntax === 2) {
if (field.packed)
opts.push("packed=true");
} else {
if (!field.packed)
opts.push("packed=false");
}
// TODO: Proper field options
}
if (opts.length)
sb.push("[" + opts.join(', ') + "]");
var opts = buildFieldOptions(field);
if (opts)
sb.push(opts);
push(sb.join(" ") + ";");
}

function buildFieldOptions(field) {
var keys;
if (!field.options || !(keys = Object.keys(field.options)).length)
return null;
var sb = [];
Object.keys(field.options).forEach(function(key) {
var val = field.options[key];
var wireType = types.packed[field.resolvedType instanceof Enum ? "uint32" : field.type];
switch (key) {
case "packed":
val = Boolean(val);
// skip when not packable or syntax default
if (wireType === undefined || (syntax === 3) === val)
return;
break;
case "default":
// skip default (resolved) default values
if (field.long && !util.longNeq(field.defaultValue, types.defaults[field.type]) || !field.long && field.defaultValue === types.defaults[field.type])
return;
// enum defaults specified as strings are type references and not enclosed in quotes
if (field.resolvedType instanceof Enum)
break;
// otherwise fallthrough
default:
val = value(val);
break;
}
sb.push(key + "=" + val);
});
return sb.length
? "[" + sb.join(", ") + "]"
: null;
}

function consolidateExtends(nested) {
var ext = {};
nested = nested.filter(function(obj) {
Expand Down Expand Up @@ -201,7 +249,8 @@ function buildOneOf(oneof) {
var field = oneof.parent.get(fieldName);
if (first)
push(""), first = false;
push(field.type + " " + under_score(field.name) + " = " + field.id + ";");
var opts = buildFieldOptions(field);
push(field.type + " " + under_score(field.name) + " = " + field.id + (opts ? " " + opts : "") + ";");
});
--indent;
push("}");
Expand Down
39 changes: 31 additions & 8 deletions dist/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/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.

7 changes: 5 additions & 2 deletions src/namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,17 @@ NamespacePrototype.define = function define(path, json) {
NamespacePrototype.resolveAll = function resolve() {
var nested = this.getNestedArray(), i = 0;
while (i < nested.length)
nested[i++].resolve();
if (nested[i] instanceof Namespace)
nested[i++].resolveAll();
else
nested[i++].resolve();
return ReflectionObject.prototype.resolve.call(this);
};

/**
* Looks up the reflection object at the specified path, relative to this namespace.
* @param {string|string[]} path Path to look up
* @param {boolean} [parentAlreadyChecked] Whether the parent has already been checked
* @param {boolean} [parentAlreadyChecked=false] Whether the parent has already been checked
* @returns {?ReflectionObject} Looked up object or `null` if none could be found
*/
NamespacePrototype.lookup = function lookup(path, parentAlreadyChecked) {
Expand Down
2 changes: 1 addition & 1 deletion src/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function parse(source, root) {
return sign * parseInt(token, 16);
if (/^0[0-7]+$/.test(token))
return sign * parseInt(token, 8);
if (/^[0-9]*(?:\.[0-9]*)?(?:[e][+-]?[0-9]+)?$/.test(tokenLower))
if (/^(?!e)[0-9]*(?:\.[0-9]*)?(?:[e][+-]?[0-9]+)?$/.test(tokenLower))
return sign * parseFloat(token);
throw illegal(token, 'number');
}
Expand Down
19 changes: 17 additions & 2 deletions src/tokenize.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"use strict";
/* eslint-disable default-case, callback-return */
module.exports = tokenize;

var delimRe = /[\s{}=;:[\],'"()<>]/g,
Expand All @@ -20,12 +19,27 @@ var s_nl = "\n",
s_sl = '/',
s_as = '*';

function unescape(str) {
return str.replace(/\\(.?)/g, function($0, $1) {
switch ($1) {
case "\\":
case "":
return $1;
case "0":
return "\u0000";
default:
return $1;
}
});
}

/**
* Tokenizes the given .proto source and returns an object with useful utility functions.
* @param {string} source Source contents
* @returns {TokenizerHandle} Tokenizer handle
*/
function tokenize(source) {
/* eslint-disable default-case, callback-return */
source = source.toString();

var offset = 0,
Expand Down Expand Up @@ -60,7 +74,7 @@ function tokenize(source) {
offset = re.lastIndex;
push(stringDelim);
stringDelim = null;
return match[1];
return unescape(match[1]);
}

/**
Expand Down Expand Up @@ -188,4 +202,5 @@ function tokenize(source) {
push: push,
skip: skip
};
/* eslint-enable default-case, callback-return */
}
6 changes: 3 additions & 3 deletions types/protobuf.js.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* protobuf.js v6.0.0-dev TypeScript definitions
* Generated Mon, 28 Nov 2016 15:09:05 UTC
* protobuf.js v6.0.0 TypeScript definitions
* Generated Tue, 29 Nov 2016 12:18:27 UTC
*/
declare module protobuf {

Expand Down Expand Up @@ -704,7 +704,7 @@ declare module protobuf {
/**
* Looks up the reflection object at the specified path, relative to this namespace.
* @param {string|string[]} path Path to look up
* @param {boolean} [parentAlreadyChecked] Whether the parent has already been checked
* @param {boolean} [parentAlreadyChecked=false] Whether the parent has already been checked
* @returns {?ReflectionObject} Looked up object or `null` if none could be found
*/
lookup(path: (string|string[]), parentAlreadyChecked?: boolean): ReflectionObject;
Expand Down

0 comments on commit 4affa1b

Please sign in to comment.