protobufjs 3.6.0 → 3.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/proto2js +16 -4
- package/bower.json +1 -1
- package/dist/ProtoBuf.js +645 -441
- package/dist/ProtoBuf.min.js +96 -96
- package/dist/ProtoBuf.min.js.gz +0 -0
- package/dist/ProtoBuf.min.map +2 -2
- package/dist/ProtoBuf.noparse.js +520 -357
- package/dist/ProtoBuf.noparse.min.js +68 -66
- package/dist/ProtoBuf.noparse.min.js.gz +0 -0
- package/dist/ProtoBuf.noparse.min.map +3 -3
- package/docs/ProtoBuf.Builder.Message.html +673 -135
- package/docs/ProtoBuf.Builder.Service.html +58 -19
- package/docs/ProtoBuf.Builder.html +374 -46
- package/docs/ProtoBuf.DotProto.Parser.html +58 -19
- package/docs/ProtoBuf.DotProto.Tokenizer.html +104 -19
- package/docs/ProtoBuf.DotProto.html +16 -10
- package/docs/ProtoBuf.Reflect.Enum.Value.html +207 -33
- package/docs/ProtoBuf.Reflect.Enum.html +318 -56
- package/docs/ProtoBuf.Reflect.Extension.html +53 -13
- package/docs/ProtoBuf.Reflect.Message.ExtensionField.html +450 -68
- package/docs/ProtoBuf.Reflect.Message.Field.html +454 -51
- package/docs/ProtoBuf.Reflect.Message.OneOf.html +1044 -0
- package/docs/ProtoBuf.Reflect.Message.html +378 -64
- package/docs/ProtoBuf.Reflect.Namespace.html +333 -51
- package/docs/ProtoBuf.Reflect.Service.Method.html +228 -35
- package/docs/ProtoBuf.Reflect.Service.RPCMethod.html +262 -41
- package/docs/ProtoBuf.Reflect.Service.html +318 -56
- package/docs/ProtoBuf.Reflect.T.html +210 -25
- package/docs/ProtoBuf.Reflect.html +17 -11
- package/docs/ProtoBuf.Util.html +59 -13
- package/docs/ProtoBuf.html +235 -67
- package/docs/ProtoBuf.js.html +648 -443
- package/docs/index.html +4 -2
- package/docs/styles/jsdoc-default.css +2 -2
- package/examples/protoify/.npmignore +2 -0
- package/examples/protoify/README.md +28 -0
- package/examples/protoify/index.js +147 -0
- package/examples/protoify/json.js +123 -0
- package/examples/protoify/json.json +123 -0
- package/examples/protoify/json.proto +30 -0
- package/examples/protoify/package.json +15 -0
- package/examples/protoify/test.js +56 -0
- package/examples/websocket/README.md +1 -0
- package/examples/websocket/package.json +1 -1
- package/externs/ProtoBuf.js +922 -922
- package/package.json +3 -3
- package/scripts/build.js +58 -58
- package/src/ProtoBuf/Builder/Message.js +107 -77
- package/src/ProtoBuf/Builder/Service.js +8 -5
- package/src/ProtoBuf/Builder.js +71 -37
- package/src/ProtoBuf/DotProto/Parser.js +108 -72
- package/src/ProtoBuf/DotProto/Tokenizer.js +17 -11
- package/src/ProtoBuf/Lang.js +1 -1
- package/src/ProtoBuf/Reflect/Enum/Value.js +3 -2
- package/src/ProtoBuf/Reflect/Enum.js +9 -5
- package/src/ProtoBuf/Reflect/Extension.js +4 -3
- package/src/ProtoBuf/Reflect/Message/ExtensionField.js +4 -3
- package/src/ProtoBuf/Reflect/Message/Field.js +45 -26
- package/src/ProtoBuf/Reflect/Message/OneOf.js +19 -0
- package/src/ProtoBuf/Reflect/Message.js +36 -19
- package/src/ProtoBuf/Reflect/Namespace.js +19 -15
- package/src/ProtoBuf/Reflect/Service/Method.js +9 -5
- package/src/ProtoBuf/Reflect/Service/RPCMethod.js +3 -2
- package/src/ProtoBuf/Reflect/Service.js +9 -5
- package/src/ProtoBuf/Reflect/T.js +20 -6
- package/src/ProtoBuf/Reflect.js +9 -0
- package/src/ProtoBuf/Util.js +132 -132
- package/src/ProtoBuf.js +15 -17
- package/src/google/protobuf/descriptor.json +33 -13
- package/tests/bench.txt +373 -373
- package/tests/complex.json +8 -4
- package/tests/custom-options.json +169 -169
- package/tests/extend.json +71 -71
- package/tests/nodeunit-browser/nodeunit.css +70 -70
- package/tests/nodeunit-browser/nodeunit.js +2108 -2108
- package/tests/oneof.proto +6 -0
- package/tests/options.json +32 -32
- package/tests/options.proto +2 -0
- package/tests/proto2js/Bar.json +46 -46
- package/tests/suite.js +83 -12
- package/.idea/.name +0 -1
- package/.idea/ProtoBuf.iml +0 -9
- package/.idea/dictionaries/Daniel.xml +0 -7
- package/.idea/encodings.xml +0 -5
- package/.idea/misc.xml +0 -5
- package/.idea/modules.xml +0 -9
- package/.idea/scopes/scope_settings.xml +0 -5
- package/.idea/vcs.xml +0 -7
- package/.idea/workspace.xml +0 -551
- package/NOTICE +0 -2
- package/sandbox/issue146/MyOptions.proto +0 -28
- package/sandbox/issue146/Sample.proto +0 -21
- package/sandbox/issue146/main.js +0 -3
- package/sandbox/issue147/enum.proto +0 -8
- package/sandbox/issue147/main.js +0 -3
- package/sandbox/issue42/innerextend.proto +0 -18
- package/sandbox/issue42/main.js +0 -8
- package/sandbox/issue42/outerextend.proto +0 -17
- package/v8.log +0 -3828
package/dist/ProtoBuf.js
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* @const
|
|
39
39
|
* @expose
|
|
40
40
|
*/
|
|
41
|
-
ProtoBuf.VERSION = "3.
|
|
41
|
+
ProtoBuf.VERSION = "3.8.2";
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Wire types.
|
|
@@ -234,138 +234,138 @@
|
|
|
234
234
|
*/
|
|
235
235
|
ProtoBuf.populateAccessors = true;
|
|
236
236
|
|
|
237
|
-
/**
|
|
238
|
-
* @alias ProtoBuf.Util
|
|
239
|
-
* @expose
|
|
240
|
-
*/
|
|
241
|
-
ProtoBuf.Util = (function() {
|
|
242
|
-
"use strict";
|
|
243
|
-
|
|
244
|
-
// Object.create polyfill
|
|
245
|
-
// ref: https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
|
|
246
|
-
if (!Object.create)
|
|
247
|
-
/** @expose */
|
|
248
|
-
Object.create = function (o) {
|
|
249
|
-
if (arguments.length > 1)
|
|
250
|
-
throw Error('Object.create polyfill only accepts the first parameter.');
|
|
251
|
-
function F() {}
|
|
252
|
-
F.prototype = o;
|
|
253
|
-
return new F();
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* ProtoBuf utilities.
|
|
258
|
-
* @exports ProtoBuf.Util
|
|
259
|
-
* @namespace
|
|
260
|
-
*/
|
|
261
|
-
var Util = {};
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Flag if running in node (fs is available) or not.
|
|
265
|
-
* @type {boolean}
|
|
266
|
-
* @const
|
|
267
|
-
* @expose
|
|
268
|
-
*/
|
|
269
|
-
Util.IS_NODE = false;
|
|
270
|
-
try {
|
|
271
|
-
// There is no reliable way to detect node.js as an environment, so our
|
|
272
|
-
// best bet is to feature-detect what we actually need.
|
|
273
|
-
Util.IS_NODE =
|
|
274
|
-
typeof require === 'function' &&
|
|
275
|
-
typeof require("fs").readFileSync === 'function' &&
|
|
276
|
-
typeof require("path").resolve === 'function';
|
|
277
|
-
} catch (e) {}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Constructs a XMLHttpRequest object.
|
|
281
|
-
* @return {XMLHttpRequest}
|
|
282
|
-
* @throws {Error} If XMLHttpRequest is not supported
|
|
283
|
-
* @expose
|
|
284
|
-
*/
|
|
285
|
-
Util.XHR = function() {
|
|
286
|
-
// No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
|
|
287
|
-
var XMLHttpFactories = [
|
|
288
|
-
function () {return new XMLHttpRequest()},
|
|
289
|
-
function () {return new ActiveXObject("Msxml2.XMLHTTP")},
|
|
290
|
-
function () {return new ActiveXObject("Msxml3.XMLHTTP")},
|
|
291
|
-
function () {return new ActiveXObject("Microsoft.XMLHTTP")}
|
|
292
|
-
];
|
|
293
|
-
/** @type {?XMLHttpRequest} */
|
|
294
|
-
var xhr = null;
|
|
295
|
-
for (var i=0;i<XMLHttpFactories.length;i++) {
|
|
296
|
-
try { xhr = XMLHttpFactories[i](); }
|
|
297
|
-
catch (e) { continue; }
|
|
298
|
-
break;
|
|
299
|
-
}
|
|
300
|
-
if (!xhr)
|
|
301
|
-
throw Error("XMLHttpRequest is not supported");
|
|
302
|
-
return xhr;
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Fetches a resource.
|
|
307
|
-
* @param {string} path Resource path
|
|
308
|
-
* @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
|
|
309
|
-
* be fetched synchronously. If the request failed, contents will be null.
|
|
310
|
-
* @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
|
|
311
|
-
* @expose
|
|
312
|
-
*/
|
|
313
|
-
Util.fetch = function(path, callback) {
|
|
314
|
-
if (callback && typeof callback != 'function')
|
|
315
|
-
callback = null;
|
|
316
|
-
if (Util.IS_NODE) {
|
|
317
|
-
if (callback) {
|
|
318
|
-
require("fs").readFile(path, function(err, data) {
|
|
319
|
-
if (err)
|
|
320
|
-
callback(null);
|
|
321
|
-
else
|
|
322
|
-
callback(""+data);
|
|
323
|
-
});
|
|
324
|
-
} else
|
|
325
|
-
try {
|
|
326
|
-
return require("fs").readFileSync(path);
|
|
327
|
-
} catch (e) {
|
|
328
|
-
return null;
|
|
329
|
-
}
|
|
330
|
-
} else {
|
|
331
|
-
var xhr = Util.XHR();
|
|
332
|
-
xhr.open('GET', path, callback ? true : false);
|
|
333
|
-
// xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
|
|
334
|
-
xhr.setRequestHeader('Accept', 'text/plain');
|
|
335
|
-
if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
|
|
336
|
-
if (callback) {
|
|
337
|
-
xhr.onreadystatechange = function() {
|
|
338
|
-
if (xhr.readyState != 4) return;
|
|
339
|
-
if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
|
|
340
|
-
callback(xhr.responseText);
|
|
341
|
-
else
|
|
342
|
-
callback(null);
|
|
343
|
-
};
|
|
344
|
-
if (xhr.readyState == 4)
|
|
345
|
-
return;
|
|
346
|
-
xhr.send(null);
|
|
347
|
-
} else {
|
|
348
|
-
xhr.send(null);
|
|
349
|
-
if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
|
|
350
|
-
return xhr.responseText;
|
|
351
|
-
return null;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Tests if an object is an array.
|
|
358
|
-
* @function
|
|
359
|
-
* @param {*} obj Object to test
|
|
360
|
-
* @returns {boolean} true if it is an array, else false
|
|
361
|
-
* @expose
|
|
362
|
-
*/
|
|
363
|
-
Util.isArray = Array.isArray || function(obj) {
|
|
364
|
-
return Object.prototype.toString.call(obj) === "[object Array]";
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
return Util;
|
|
368
|
-
})();
|
|
237
|
+
/**
|
|
238
|
+
* @alias ProtoBuf.Util
|
|
239
|
+
* @expose
|
|
240
|
+
*/
|
|
241
|
+
ProtoBuf.Util = (function() {
|
|
242
|
+
"use strict";
|
|
243
|
+
|
|
244
|
+
// Object.create polyfill
|
|
245
|
+
// ref: https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
|
|
246
|
+
if (!Object.create)
|
|
247
|
+
/** @expose */
|
|
248
|
+
Object.create = function (o) {
|
|
249
|
+
if (arguments.length > 1)
|
|
250
|
+
throw Error('Object.create polyfill only accepts the first parameter.');
|
|
251
|
+
function F() {}
|
|
252
|
+
F.prototype = o;
|
|
253
|
+
return new F();
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* ProtoBuf utilities.
|
|
258
|
+
* @exports ProtoBuf.Util
|
|
259
|
+
* @namespace
|
|
260
|
+
*/
|
|
261
|
+
var Util = {};
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Flag if running in node (fs is available) or not.
|
|
265
|
+
* @type {boolean}
|
|
266
|
+
* @const
|
|
267
|
+
* @expose
|
|
268
|
+
*/
|
|
269
|
+
Util.IS_NODE = false;
|
|
270
|
+
try {
|
|
271
|
+
// There is no reliable way to detect node.js as an environment, so our
|
|
272
|
+
// best bet is to feature-detect what we actually need.
|
|
273
|
+
Util.IS_NODE =
|
|
274
|
+
typeof require === 'function' &&
|
|
275
|
+
typeof require("fs").readFileSync === 'function' &&
|
|
276
|
+
typeof require("path").resolve === 'function';
|
|
277
|
+
} catch (e) {}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Constructs a XMLHttpRequest object.
|
|
281
|
+
* @return {XMLHttpRequest}
|
|
282
|
+
* @throws {Error} If XMLHttpRequest is not supported
|
|
283
|
+
* @expose
|
|
284
|
+
*/
|
|
285
|
+
Util.XHR = function() {
|
|
286
|
+
// No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
|
|
287
|
+
var XMLHttpFactories = [
|
|
288
|
+
function () {return new XMLHttpRequest()},
|
|
289
|
+
function () {return new ActiveXObject("Msxml2.XMLHTTP")},
|
|
290
|
+
function () {return new ActiveXObject("Msxml3.XMLHTTP")},
|
|
291
|
+
function () {return new ActiveXObject("Microsoft.XMLHTTP")}
|
|
292
|
+
];
|
|
293
|
+
/** @type {?XMLHttpRequest} */
|
|
294
|
+
var xhr = null;
|
|
295
|
+
for (var i=0;i<XMLHttpFactories.length;i++) {
|
|
296
|
+
try { xhr = XMLHttpFactories[i](); }
|
|
297
|
+
catch (e) { continue; }
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
if (!xhr)
|
|
301
|
+
throw Error("XMLHttpRequest is not supported");
|
|
302
|
+
return xhr;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Fetches a resource.
|
|
307
|
+
* @param {string} path Resource path
|
|
308
|
+
* @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
|
|
309
|
+
* be fetched synchronously. If the request failed, contents will be null.
|
|
310
|
+
* @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
|
|
311
|
+
* @expose
|
|
312
|
+
*/
|
|
313
|
+
Util.fetch = function(path, callback) {
|
|
314
|
+
if (callback && typeof callback != 'function')
|
|
315
|
+
callback = null;
|
|
316
|
+
if (Util.IS_NODE) {
|
|
317
|
+
if (callback) {
|
|
318
|
+
require("fs").readFile(path, function(err, data) {
|
|
319
|
+
if (err)
|
|
320
|
+
callback(null);
|
|
321
|
+
else
|
|
322
|
+
callback(""+data);
|
|
323
|
+
});
|
|
324
|
+
} else
|
|
325
|
+
try {
|
|
326
|
+
return require("fs").readFileSync(path);
|
|
327
|
+
} catch (e) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
var xhr = Util.XHR();
|
|
332
|
+
xhr.open('GET', path, callback ? true : false);
|
|
333
|
+
// xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
|
|
334
|
+
xhr.setRequestHeader('Accept', 'text/plain');
|
|
335
|
+
if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
|
|
336
|
+
if (callback) {
|
|
337
|
+
xhr.onreadystatechange = function() {
|
|
338
|
+
if (xhr.readyState != 4) return;
|
|
339
|
+
if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
|
|
340
|
+
callback(xhr.responseText);
|
|
341
|
+
else
|
|
342
|
+
callback(null);
|
|
343
|
+
};
|
|
344
|
+
if (xhr.readyState == 4)
|
|
345
|
+
return;
|
|
346
|
+
xhr.send(null);
|
|
347
|
+
} else {
|
|
348
|
+
xhr.send(null);
|
|
349
|
+
if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
|
|
350
|
+
return xhr.responseText;
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Tests if an object is an array.
|
|
358
|
+
* @function
|
|
359
|
+
* @param {*} obj Object to test
|
|
360
|
+
* @returns {boolean} true if it is an array, else false
|
|
361
|
+
* @expose
|
|
362
|
+
*/
|
|
363
|
+
Util.isArray = Array.isArray || function(obj) {
|
|
364
|
+
return Object.prototype.toString.call(obj) === "[object Array]";
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
return Util;
|
|
368
|
+
})();
|
|
369
369
|
|
|
370
370
|
/**
|
|
371
371
|
* Language expressions.
|
|
@@ -402,7 +402,7 @@
|
|
|
402
402
|
ID: /^(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
|
|
403
403
|
NEGID: /^\-?(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
|
|
404
404
|
WHITESPACE: /\s/,
|
|
405
|
-
STRING: /
|
|
405
|
+
STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
|
|
406
406
|
BOOL: /^(?:true|false)$/i
|
|
407
407
|
};
|
|
408
408
|
|
|
@@ -423,7 +423,7 @@
|
|
|
423
423
|
/**
|
|
424
424
|
* Constructs a new Tokenizer.
|
|
425
425
|
* @exports ProtoBuf.DotProto.Tokenizer
|
|
426
|
-
* @class
|
|
426
|
+
* @class prototype tokenizer
|
|
427
427
|
* @param {string} proto Proto to tokenize
|
|
428
428
|
* @constructor
|
|
429
429
|
*/
|
|
@@ -472,22 +472,28 @@
|
|
|
472
472
|
this.stringEndsWith = Lang.STRINGCLOSE;
|
|
473
473
|
};
|
|
474
474
|
|
|
475
|
+
/**
|
|
476
|
+
* @alias ProtoBuf.DotProto.Tokenizer.prototype
|
|
477
|
+
* @inner
|
|
478
|
+
*/
|
|
479
|
+
var TokenizerPrototype = Tokenizer.prototype;
|
|
480
|
+
|
|
475
481
|
/**
|
|
476
482
|
* Reads a string beginning at the current index.
|
|
477
483
|
* @return {string} The string
|
|
478
484
|
* @throws {Error} If it's not a valid string
|
|
479
485
|
* @private
|
|
480
486
|
*/
|
|
481
|
-
|
|
487
|
+
TokenizerPrototype._readString = function() {
|
|
482
488
|
Lang.STRING.lastIndex = this.index-1; // Include the open quote
|
|
483
489
|
var match;
|
|
484
490
|
if ((match = Lang.STRING.exec(this.source)) !== null) {
|
|
485
|
-
var s = match[1];
|
|
491
|
+
var s = typeof match[1] !== 'undefined' ? match[1] : match[2];
|
|
486
492
|
this.index = Lang.STRING.lastIndex;
|
|
487
493
|
this.stack.push(this.stringEndsWith);
|
|
488
494
|
return s;
|
|
489
495
|
}
|
|
490
|
-
throw Error("
|
|
496
|
+
throw Error("Unterminated string at line "+this.line+", index "+this.index);
|
|
491
497
|
};
|
|
492
498
|
|
|
493
499
|
/**
|
|
@@ -496,7 +502,7 @@
|
|
|
496
502
|
* @throws {Error} If it's not a valid proto file
|
|
497
503
|
* @expose
|
|
498
504
|
*/
|
|
499
|
-
|
|
505
|
+
TokenizerPrototype.next = function() {
|
|
500
506
|
if (this.stack.length > 0)
|
|
501
507
|
return this.stack.shift();
|
|
502
508
|
if (this.index >= this.source.length)
|
|
@@ -539,7 +545,7 @@
|
|
|
539
545
|
this.index++;
|
|
540
546
|
repeat = true;
|
|
541
547
|
} else
|
|
542
|
-
throw Error("
|
|
548
|
+
throw Error("Unterminated comment at line "+this.line+": /"+this.source.charAt(this.index));
|
|
543
549
|
}
|
|
544
550
|
} while (repeat);
|
|
545
551
|
if (this.index === this.source.length) return null;
|
|
@@ -570,7 +576,7 @@
|
|
|
570
576
|
* @throws {Error} If it's not a valid proto file
|
|
571
577
|
* @expose
|
|
572
578
|
*/
|
|
573
|
-
|
|
579
|
+
TokenizerPrototype.peek = function() {
|
|
574
580
|
if (this.stack.length === 0) {
|
|
575
581
|
var token = this.next();
|
|
576
582
|
if (token === null)
|
|
@@ -585,7 +591,7 @@
|
|
|
585
591
|
* @return {string} String representation as of "Tokenizer(index/length)"
|
|
586
592
|
* @expose
|
|
587
593
|
*/
|
|
588
|
-
|
|
594
|
+
TokenizerPrototype.toString = function() {
|
|
589
595
|
return "Tokenizer("+this.index+"/"+this.source.length+" at line "+this.line+")";
|
|
590
596
|
};
|
|
591
597
|
|
|
@@ -598,7 +604,7 @@
|
|
|
598
604
|
/**
|
|
599
605
|
* Constructs a new Parser.
|
|
600
606
|
* @exports ProtoBuf.DotProto.Parser
|
|
601
|
-
* @class
|
|
607
|
+
* @class prototype parser
|
|
602
608
|
* @param {string} proto Protocol source
|
|
603
609
|
* @constructor
|
|
604
610
|
*/
|
|
@@ -612,13 +618,19 @@
|
|
|
612
618
|
this.tn = new Tokenizer(proto);
|
|
613
619
|
};
|
|
614
620
|
|
|
621
|
+
/**
|
|
622
|
+
* @alias ProtoBuf.DotProto.Parser.prototype
|
|
623
|
+
* @inner
|
|
624
|
+
*/
|
|
625
|
+
var ParserPrototype = Parser.prototype;
|
|
626
|
+
|
|
615
627
|
/**
|
|
616
628
|
* Runs the parser.
|
|
617
629
|
* @return {{package: string|null, messages: Array.<object>, enums: Array.<object>, imports: Array.<string>, options: object<string,*>}}
|
|
618
630
|
* @throws {Error} If the source cannot be parsed
|
|
619
631
|
* @expose
|
|
620
632
|
*/
|
|
621
|
-
|
|
633
|
+
ParserPrototype.parse = function() {
|
|
622
634
|
var topLevel = {
|
|
623
635
|
"name": "[ROOT]", // temporary
|
|
624
636
|
"package": null,
|
|
@@ -633,12 +645,12 @@
|
|
|
633
645
|
switch (token) {
|
|
634
646
|
case 'package':
|
|
635
647
|
if (!head || topLevel["package"] !== null)
|
|
636
|
-
throw Error("
|
|
648
|
+
throw Error("Unexpected package at line "+this.tn.line);
|
|
637
649
|
topLevel["package"] = this._parsePackage(token);
|
|
638
650
|
break;
|
|
639
651
|
case 'import':
|
|
640
652
|
if (!head)
|
|
641
|
-
throw Error("
|
|
653
|
+
throw Error("Unexpected import at line "+this.tn.line);
|
|
642
654
|
topLevel.imports.push(this._parseImport(token));
|
|
643
655
|
break;
|
|
644
656
|
case 'message':
|
|
@@ -651,7 +663,7 @@
|
|
|
651
663
|
break;
|
|
652
664
|
case 'option':
|
|
653
665
|
if (!head)
|
|
654
|
-
throw Error("
|
|
666
|
+
throw Error("Unexpected option at line "+this.tn.line);
|
|
655
667
|
this._parseOption(topLevel, token);
|
|
656
668
|
break;
|
|
657
669
|
case 'service':
|
|
@@ -664,7 +676,7 @@
|
|
|
664
676
|
this._parseIgnoredStatement(topLevel, token);
|
|
665
677
|
break;
|
|
666
678
|
default:
|
|
667
|
-
throw Error("
|
|
679
|
+
throw Error("Unexpected token at line "+this.tn.line+": "+token);
|
|
668
680
|
}
|
|
669
681
|
}
|
|
670
682
|
delete topLevel["name"];
|
|
@@ -678,7 +690,7 @@
|
|
|
678
690
|
* @throws {Error} If the number value is invalid
|
|
679
691
|
* @private
|
|
680
692
|
*/
|
|
681
|
-
|
|
693
|
+
ParserPrototype._parseNumber = function(val) {
|
|
682
694
|
var sign = 1;
|
|
683
695
|
if (val.charAt(0) == '-')
|
|
684
696
|
sign = -1,
|
|
@@ -696,18 +708,17 @@
|
|
|
696
708
|
|
|
697
709
|
/**
|
|
698
710
|
* Parses a (possibly multiline) string.
|
|
699
|
-
* @param {string} context Context description
|
|
700
711
|
* @returns {string}
|
|
701
712
|
* @private
|
|
702
713
|
*/
|
|
703
|
-
|
|
714
|
+
ParserPrototype._parseString = function() {
|
|
704
715
|
var value = "", token;
|
|
705
716
|
do {
|
|
706
717
|
token = this.tn.next(); // Known to be = this.tn.stringEndsWith
|
|
707
718
|
value += this.tn.next();
|
|
708
719
|
token = this.tn.next();
|
|
709
720
|
if (token !== this.tn.stringEndsWith)
|
|
710
|
-
throw Error("Illegal end of string
|
|
721
|
+
throw Error("Illegal end of string at line "+this.tn.line+": "+token);
|
|
711
722
|
token = this.tn.peek();
|
|
712
723
|
} while (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ);
|
|
713
724
|
return value;
|
|
@@ -721,7 +732,7 @@
|
|
|
721
732
|
* @throws {Error} If the ID value is invalid
|
|
722
733
|
* @private
|
|
723
734
|
*/
|
|
724
|
-
|
|
735
|
+
ParserPrototype._parseId = function(val, neg) {
|
|
725
736
|
var id = -1;
|
|
726
737
|
var sign = 1;
|
|
727
738
|
if (val.charAt(0) == '-')
|
|
@@ -734,10 +745,10 @@
|
|
|
734
745
|
else if (Lang.NUMBER_OCT.test(val))
|
|
735
746
|
id = parseInt(val.substring(1), 8);
|
|
736
747
|
else
|
|
737
|
-
throw Error("Illegal
|
|
748
|
+
throw Error("Illegal id at line "+this.tn.line+": "+(sign < 0 ? '-' : '')+val);
|
|
738
749
|
id = (sign*id)|0; // Force to 32bit
|
|
739
750
|
if (!neg && id < 0)
|
|
740
|
-
throw Error("Illegal
|
|
751
|
+
throw Error("Illegal id at line "+this.tn.line+": "+(sign < 0 ? '-' : '')+val);
|
|
741
752
|
return id;
|
|
742
753
|
};
|
|
743
754
|
|
|
@@ -748,14 +759,14 @@
|
|
|
748
759
|
* @throws {Error} If the package definition cannot be parsed
|
|
749
760
|
* @private
|
|
750
761
|
*/
|
|
751
|
-
|
|
762
|
+
ParserPrototype._parsePackage = function(token) {
|
|
752
763
|
token = this.tn.next();
|
|
753
764
|
if (!Lang.TYPEREF.test(token))
|
|
754
|
-
throw Error("Illegal package at line "+this.tn.line+": "+token);
|
|
765
|
+
throw Error("Illegal package name at line "+this.tn.line+": "+token);
|
|
755
766
|
var pkg = token;
|
|
756
767
|
token = this.tn.next();
|
|
757
768
|
if (token != Lang.END)
|
|
758
|
-
throw Error("Illegal end of package at line "+this.tn.line+": "+token
|
|
769
|
+
throw Error("Illegal end of package at line "+this.tn.line+": "+token);
|
|
759
770
|
return pkg;
|
|
760
771
|
};
|
|
761
772
|
|
|
@@ -766,17 +777,17 @@
|
|
|
766
777
|
* @throws {Error} If the import definition cannot be parsed
|
|
767
778
|
* @private
|
|
768
779
|
*/
|
|
769
|
-
|
|
780
|
+
ParserPrototype._parseImport = function(token) {
|
|
770
781
|
token = this.tn.peek();
|
|
771
782
|
if (token === "public")
|
|
772
783
|
this.tn.next(),
|
|
773
784
|
token = this.tn.peek();
|
|
774
785
|
if (token !== Lang.STRINGOPEN && token !== Lang.STRINGOPEN_SQ)
|
|
775
|
-
throw Error("Illegal import at line "+this.tn.line+": "+token
|
|
776
|
-
var imported = this._parseString(
|
|
786
|
+
throw Error("Illegal start of import at line "+this.tn.line+": "+token);
|
|
787
|
+
var imported = this._parseString();
|
|
777
788
|
token = this.tn.next();
|
|
778
789
|
if (token !== Lang.END)
|
|
779
|
-
throw Error("Illegal import at line "+this.tn.line+": "+token
|
|
790
|
+
throw Error("Illegal end of import at line "+this.tn.line+": "+token);
|
|
780
791
|
return imported;
|
|
781
792
|
};
|
|
782
793
|
|
|
@@ -787,7 +798,7 @@
|
|
|
787
798
|
* @throws {Error} If the option cannot be parsed
|
|
788
799
|
* @private
|
|
789
800
|
*/
|
|
790
|
-
|
|
801
|
+
ParserPrototype._parseOption = function(parent, token) {
|
|
791
802
|
token = this.tn.next();
|
|
792
803
|
var custom = false;
|
|
793
804
|
if (token == Lang.COPTOPEN)
|
|
@@ -796,12 +807,12 @@
|
|
|
796
807
|
if (!Lang.TYPEREF.test(token))
|
|
797
808
|
// we can allow options of the form google.protobuf.* since they will just get ignored anyways
|
|
798
809
|
if (!/google\.protobuf\./.test(token))
|
|
799
|
-
throw Error("Illegal option in message "+parent.name+" at line "+this.tn.line+": "+token);
|
|
810
|
+
throw Error("Illegal option name in message "+parent.name+" at line "+this.tn.line+": "+token);
|
|
800
811
|
var name = token;
|
|
801
812
|
token = this.tn.next();
|
|
802
813
|
if (custom) { // (my_method_option).foo, (my_method_option), some_method_option, (foo.my_option).bar
|
|
803
814
|
if (token !== Lang.COPTCLOSE)
|
|
804
|
-
throw Error("Illegal
|
|
815
|
+
throw Error("Illegal end in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
805
816
|
name = '('+name+')';
|
|
806
817
|
token = this.tn.next();
|
|
807
818
|
if (Lang.FQTYPEREF.test(token))
|
|
@@ -809,11 +820,11 @@
|
|
|
809
820
|
token = this.tn.next();
|
|
810
821
|
}
|
|
811
822
|
if (token !== Lang.EQUAL)
|
|
812
|
-
throw Error("Illegal
|
|
823
|
+
throw Error("Illegal operator in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
813
824
|
var value;
|
|
814
825
|
token = this.tn.peek();
|
|
815
826
|
if (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ)
|
|
816
|
-
value = this._parseString(
|
|
827
|
+
value = this._parseString();
|
|
817
828
|
else {
|
|
818
829
|
this.tn.next();
|
|
819
830
|
if (Lang.NUMBER.test(token))
|
|
@@ -827,7 +838,7 @@
|
|
|
827
838
|
}
|
|
828
839
|
token = this.tn.next();
|
|
829
840
|
if (token !== Lang.END)
|
|
830
|
-
throw Error("Illegal end of option in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token
|
|
841
|
+
throw Error("Illegal end of option in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
831
842
|
parent["options"][name] = value;
|
|
832
843
|
};
|
|
833
844
|
|
|
@@ -838,12 +849,12 @@
|
|
|
838
849
|
* @throws {Error} If the directive cannot be parsed
|
|
839
850
|
* @private
|
|
840
851
|
*/
|
|
841
|
-
|
|
852
|
+
ParserPrototype._parseIgnoredStatement = function(parent, keyword) {
|
|
842
853
|
var token;
|
|
843
854
|
do {
|
|
844
855
|
token = this.tn.next();
|
|
845
856
|
if (token === null)
|
|
846
|
-
throw Error("Unexpected EOF in "+parent.name+", "+keyword+"
|
|
857
|
+
throw Error("Unexpected EOF in "+parent.name+", "+keyword+" at line "+this.tn.line);
|
|
847
858
|
if (token === Lang.END)
|
|
848
859
|
break;
|
|
849
860
|
} while (true);
|
|
@@ -856,7 +867,7 @@
|
|
|
856
867
|
* @throws {Error} If the service cannot be parsed
|
|
857
868
|
* @private
|
|
858
869
|
*/
|
|
859
|
-
|
|
870
|
+
ParserPrototype._parseService = function(parent, token) {
|
|
860
871
|
token = this.tn.next();
|
|
861
872
|
if (!Lang.NAME.test(token))
|
|
862
873
|
throw Error("Illegal service name at line "+this.tn.line+": "+token);
|
|
@@ -868,7 +879,7 @@
|
|
|
868
879
|
};
|
|
869
880
|
token = this.tn.next();
|
|
870
881
|
if (token !== Lang.OPEN)
|
|
871
|
-
throw Error("Illegal
|
|
882
|
+
throw Error("Illegal start of service "+name+" at line "+this.tn.line+": "+token);
|
|
872
883
|
do {
|
|
873
884
|
token = this.tn.next();
|
|
874
885
|
if (token === "option")
|
|
@@ -876,7 +887,7 @@
|
|
|
876
887
|
else if (token === 'rpc')
|
|
877
888
|
this._parseServiceRPC(svc, token);
|
|
878
889
|
else if (token !== Lang.CLOSE)
|
|
879
|
-
throw Error("Illegal type
|
|
890
|
+
throw Error("Illegal type of service "+name+" at line "+this.tn.line+": "+token);
|
|
880
891
|
} while (token !== Lang.CLOSE);
|
|
881
892
|
parent["services"].push(svc);
|
|
882
893
|
};
|
|
@@ -887,11 +898,11 @@
|
|
|
887
898
|
* @param {string} token Initial token
|
|
888
899
|
* @private
|
|
889
900
|
*/
|
|
890
|
-
|
|
901
|
+
ParserPrototype._parseServiceRPC = function(svc, token) {
|
|
891
902
|
var type = token;
|
|
892
903
|
token = this.tn.next();
|
|
893
904
|
if (!Lang.NAME.test(token))
|
|
894
|
-
throw Error("Illegal
|
|
905
|
+
throw Error("Illegal method name in service "+svc["name"]+" at line "+this.tn.line+": "+token);
|
|
895
906
|
var name = token;
|
|
896
907
|
var method = {
|
|
897
908
|
"request": null,
|
|
@@ -900,25 +911,25 @@
|
|
|
900
911
|
};
|
|
901
912
|
token = this.tn.next();
|
|
902
913
|
if (token !== Lang.COPTOPEN)
|
|
903
|
-
throw Error("Illegal start of request type in
|
|
914
|
+
throw Error("Illegal start of request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
904
915
|
token = this.tn.next();
|
|
905
916
|
if (!Lang.TYPEREF.test(token))
|
|
906
|
-
throw Error("Illegal request type in
|
|
917
|
+
throw Error("Illegal request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
907
918
|
method["request"] = token;
|
|
908
919
|
token = this.tn.next();
|
|
909
920
|
if (token != Lang.COPTCLOSE)
|
|
910
|
-
throw Error("Illegal end of request type in
|
|
921
|
+
throw Error("Illegal end of request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
911
922
|
token = this.tn.next();
|
|
912
923
|
if (token.toLowerCase() !== "returns")
|
|
913
|
-
throw Error("Illegal
|
|
924
|
+
throw Error("Illegal delimiter in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
914
925
|
token = this.tn.next();
|
|
915
926
|
if (token != Lang.COPTOPEN)
|
|
916
|
-
throw Error("Illegal start of response type in
|
|
927
|
+
throw Error("Illegal start of response type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
917
928
|
token = this.tn.next();
|
|
918
929
|
method["response"] = token;
|
|
919
930
|
token = this.tn.next();
|
|
920
931
|
if (token !== Lang.COPTCLOSE)
|
|
921
|
-
throw Error("Illegal end of response type in
|
|
932
|
+
throw Error("Illegal end of response type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
922
933
|
token = this.tn.next();
|
|
923
934
|
if (token === Lang.OPEN) {
|
|
924
935
|
do {
|
|
@@ -926,12 +937,12 @@
|
|
|
926
937
|
if (token === 'option')
|
|
927
938
|
this._parseOption(method, token); // <- will fail for the custom-options example
|
|
928
939
|
else if (token !== Lang.CLOSE)
|
|
929
|
-
throw Error("Illegal start of option
|
|
940
|
+
throw Error("Illegal start of option inservice "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
930
941
|
} while (token !== Lang.CLOSE);
|
|
931
942
|
if (this.tn.peek() === Lang.END)
|
|
932
943
|
this.tn.next();
|
|
933
944
|
} else if (token !== Lang.END)
|
|
934
|
-
throw Error("Illegal
|
|
945
|
+
throw Error("Illegal delimiter in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
935
946
|
if (typeof svc[type] === 'undefined')
|
|
936
947
|
svc[type] = {};
|
|
937
948
|
svc[type][name] = method;
|
|
@@ -946,7 +957,7 @@
|
|
|
946
957
|
* @throws {Error} If the message cannot be parsed
|
|
947
958
|
* @private
|
|
948
959
|
*/
|
|
949
|
-
|
|
960
|
+
ParserPrototype._parseMessage = function(parent, fld, token) {
|
|
950
961
|
/** @dict */
|
|
951
962
|
var msg = {}; // Note: At some point we might want to exclude the parser, so we need a dict.
|
|
952
963
|
var isGroup = token === "group";
|
|
@@ -957,7 +968,7 @@
|
|
|
957
968
|
if (isGroup) {
|
|
958
969
|
token = this.tn.next();
|
|
959
970
|
if (token !== Lang.EQUAL)
|
|
960
|
-
throw Error("Illegal id assignment after group "+msg.name+" at line "+this.tn.line+": "+token
|
|
971
|
+
throw Error("Illegal id assignment after group "+msg.name+" at line "+this.tn.line+": "+token);
|
|
961
972
|
token = this.tn.next();
|
|
962
973
|
try {
|
|
963
974
|
fld["id"] = this._parseId(token);
|
|
@@ -970,12 +981,13 @@
|
|
|
970
981
|
msg["enums"] = [];
|
|
971
982
|
msg["messages"] = [];
|
|
972
983
|
msg["options"] = {};
|
|
984
|
+
msg["oneofs"] = {};
|
|
973
985
|
token = this.tn.next();
|
|
974
986
|
if (token === Lang.OPTOPEN && fld)
|
|
975
987
|
this._parseFieldOptions(msg, fld, token),
|
|
976
988
|
token = this.tn.next();
|
|
977
989
|
if (token !== Lang.OPEN)
|
|
978
|
-
throw Error("Illegal
|
|
990
|
+
throw Error("Illegal start of "+(isGroup ? "group" : "message")+" "+msg.name+" at line "+this.tn.line+": "+token);
|
|
979
991
|
// msg["extensions"] = undefined
|
|
980
992
|
do {
|
|
981
993
|
token = this.tn.next();
|
|
@@ -986,6 +998,8 @@
|
|
|
986
998
|
break;
|
|
987
999
|
} else if (Lang.RULE.test(token))
|
|
988
1000
|
this._parseMessageField(msg, token);
|
|
1001
|
+
else if (token === "oneof")
|
|
1002
|
+
this._parseMessageOneOf(msg, token);
|
|
989
1003
|
else if (token === "enum")
|
|
990
1004
|
this._parseEnum(msg, token);
|
|
991
1005
|
else if (token === "message")
|
|
@@ -997,7 +1011,7 @@
|
|
|
997
1011
|
else if (token === "extend")
|
|
998
1012
|
this._parseExtend(msg, token);
|
|
999
1013
|
else
|
|
1000
|
-
throw Error("Illegal token in message "+msg.name+" at line "+this.tn.line+": "+token
|
|
1014
|
+
throw Error("Illegal token in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
1001
1015
|
} while (true);
|
|
1002
1016
|
parent["messages"].push(msg);
|
|
1003
1017
|
return msg;
|
|
@@ -1007,10 +1021,11 @@
|
|
|
1007
1021
|
* Parses a message field.
|
|
1008
1022
|
* @param {Object} msg Message definition
|
|
1009
1023
|
* @param {string} token Initial token
|
|
1024
|
+
* @returns {!Object} Field descriptor
|
|
1010
1025
|
* @throws {Error} If the message field cannot be parsed
|
|
1011
1026
|
* @private
|
|
1012
1027
|
*/
|
|
1013
|
-
|
|
1028
|
+
ParserPrototype._parseMessageField = function(msg, token) {
|
|
1014
1029
|
/** @dict */
|
|
1015
1030
|
var fld = {}, grp = null;
|
|
1016
1031
|
fld["rule"] = token;
|
|
@@ -1039,21 +1054,48 @@
|
|
|
1039
1054
|
fld["name"] = token;
|
|
1040
1055
|
token = this.tn.next();
|
|
1041
1056
|
if (token !== Lang.EQUAL)
|
|
1042
|
-
throw Error("Illegal
|
|
1057
|
+
throw Error("Illegal token in field "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
1043
1058
|
token = this.tn.next();
|
|
1044
1059
|
try {
|
|
1045
1060
|
fld["id"] = this._parseId(token);
|
|
1046
1061
|
} catch (e) {
|
|
1047
|
-
throw Error("Illegal field id
|
|
1062
|
+
throw Error("Illegal field id in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
1048
1063
|
}
|
|
1049
1064
|
token = this.tn.next();
|
|
1050
1065
|
if (token === Lang.OPTOPEN)
|
|
1051
1066
|
this._parseFieldOptions(msg, fld, token),
|
|
1052
1067
|
token = this.tn.next();
|
|
1053
1068
|
if (token !== Lang.END)
|
|
1054
|
-
throw Error("Illegal
|
|
1069
|
+
throw Error("Illegal delimiter in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
1055
1070
|
}
|
|
1056
1071
|
msg["fields"].push(fld);
|
|
1072
|
+
return fld;
|
|
1073
|
+
};
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* Parses a message oneof.
|
|
1077
|
+
* @param {Object} msg Message definition
|
|
1078
|
+
* @param {string} token Initial token
|
|
1079
|
+
* @throws {Error} If the message oneof cannot be parsed
|
|
1080
|
+
* @private
|
|
1081
|
+
*/
|
|
1082
|
+
ParserPrototype._parseMessageOneOf = function(msg, token) {
|
|
1083
|
+
token = this.tn.next();
|
|
1084
|
+
if (!Lang.NAME.test(token))
|
|
1085
|
+
throw Error("Illegal oneof name in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
1086
|
+
var name = token,
|
|
1087
|
+
fld;
|
|
1088
|
+
var fields = [];
|
|
1089
|
+
token = this.tn.next();
|
|
1090
|
+
if (token !== Lang.OPEN)
|
|
1091
|
+
throw Error("Illegal start of oneof "+name+" at line "+this.tn.line+": "+token);
|
|
1092
|
+
while (this.tn.peek() !== Lang.CLOSE) {
|
|
1093
|
+
fld = this._parseMessageField(msg, "optional");
|
|
1094
|
+
fld["oneof"] = name;
|
|
1095
|
+
fields.push(fld["id"]);
|
|
1096
|
+
}
|
|
1097
|
+
this.tn.next();
|
|
1098
|
+
msg["oneofs"][name] = fields;
|
|
1057
1099
|
};
|
|
1058
1100
|
|
|
1059
1101
|
/**
|
|
@@ -1064,7 +1106,7 @@
|
|
|
1064
1106
|
* @throws {Error} If the message field options cannot be parsed
|
|
1065
1107
|
* @private
|
|
1066
1108
|
*/
|
|
1067
|
-
|
|
1109
|
+
ParserPrototype._parseFieldOptions = function(msg, fld, token) {
|
|
1068
1110
|
var first = true;
|
|
1069
1111
|
do {
|
|
1070
1112
|
token = this.tn.next();
|
|
@@ -1072,7 +1114,7 @@
|
|
|
1072
1114
|
break;
|
|
1073
1115
|
else if (token === Lang.OPTEND) {
|
|
1074
1116
|
if (first)
|
|
1075
|
-
throw Error("Illegal start of
|
|
1117
|
+
throw Error("Illegal start of options in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
1076
1118
|
token = this.tn.next();
|
|
1077
1119
|
}
|
|
1078
1120
|
this._parseFieldOption(msg, fld, token);
|
|
@@ -1088,18 +1130,18 @@
|
|
|
1088
1130
|
* @throws {Error} If the mesage field option cannot be parsed
|
|
1089
1131
|
* @private
|
|
1090
1132
|
*/
|
|
1091
|
-
|
|
1133
|
+
ParserPrototype._parseFieldOption = function(msg, fld, token) {
|
|
1092
1134
|
var custom = false;
|
|
1093
1135
|
if (token === Lang.COPTOPEN)
|
|
1094
1136
|
token = this.tn.next(),
|
|
1095
1137
|
custom = true;
|
|
1096
1138
|
if (!Lang.TYPEREF.test(token))
|
|
1097
|
-
throw Error("Illegal field option in
|
|
1139
|
+
throw Error("Illegal field option in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
1098
1140
|
var name = token;
|
|
1099
1141
|
token = this.tn.next();
|
|
1100
1142
|
if (custom) {
|
|
1101
1143
|
if (token !== Lang.COPTCLOSE)
|
|
1102
|
-
throw Error("Illegal
|
|
1144
|
+
throw Error("Illegal delimiter in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
1103
1145
|
name = '('+name+')';
|
|
1104
1146
|
token = this.tn.next();
|
|
1105
1147
|
if (Lang.FQTYPEREF.test(token))
|
|
@@ -1107,11 +1149,11 @@
|
|
|
1107
1149
|
token = this.tn.next();
|
|
1108
1150
|
}
|
|
1109
1151
|
if (token !== Lang.EQUAL)
|
|
1110
|
-
throw Error("Illegal
|
|
1152
|
+
throw Error("Illegal token in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
1111
1153
|
var value;
|
|
1112
1154
|
token = this.tn.peek();
|
|
1113
1155
|
if (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ) {
|
|
1114
|
-
value = this._parseString(
|
|
1156
|
+
value = this._parseString();
|
|
1115
1157
|
} else if (Lang.NUMBER.test(token, true))
|
|
1116
1158
|
value = this._parseNumber(this.tn.next(), true);
|
|
1117
1159
|
else if (Lang.BOOL.test(token))
|
|
@@ -1119,7 +1161,7 @@
|
|
|
1119
1161
|
else if (Lang.TYPEREF.test(token))
|
|
1120
1162
|
value = this.tn.next(); // TODO: Resolve?
|
|
1121
1163
|
else
|
|
1122
|
-
throw Error("Illegal
|
|
1164
|
+
throw Error("Illegal value in message "+msg.name+"#"+fld.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
1123
1165
|
fld["options"][name] = value;
|
|
1124
1166
|
};
|
|
1125
1167
|
|
|
@@ -1130,7 +1172,7 @@
|
|
|
1130
1172
|
* @throws {Error} If the enum cannot be parsed
|
|
1131
1173
|
* @private
|
|
1132
1174
|
*/
|
|
1133
|
-
|
|
1175
|
+
ParserPrototype._parseEnum = function(msg, token) {
|
|
1134
1176
|
/** @dict */
|
|
1135
1177
|
var enm = {};
|
|
1136
1178
|
token = this.tn.next();
|
|
@@ -1139,7 +1181,7 @@
|
|
|
1139
1181
|
enm["name"] = token;
|
|
1140
1182
|
token = this.tn.next();
|
|
1141
1183
|
if (token !== Lang.OPEN)
|
|
1142
|
-
throw Error("Illegal
|
|
1184
|
+
throw Error("Illegal start of enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
1143
1185
|
enm["values"] = [];
|
|
1144
1186
|
enm["options"] = {};
|
|
1145
1187
|
do {
|
|
@@ -1154,7 +1196,7 @@
|
|
|
1154
1196
|
this._parseOption(enm, token);
|
|
1155
1197
|
else {
|
|
1156
1198
|
if (!Lang.NAME.test(token))
|
|
1157
|
-
throw Error("Illegal
|
|
1199
|
+
throw Error("Illegal name in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
1158
1200
|
this._parseEnumValue(enm, token);
|
|
1159
1201
|
}
|
|
1160
1202
|
} while (true);
|
|
@@ -1168,18 +1210,18 @@
|
|
|
1168
1210
|
* @throws {Error} If the enum value cannot be parsed
|
|
1169
1211
|
* @private
|
|
1170
1212
|
*/
|
|
1171
|
-
|
|
1213
|
+
ParserPrototype._parseEnumValue = function(enm, token) {
|
|
1172
1214
|
/** @dict */
|
|
1173
1215
|
var val = {};
|
|
1174
1216
|
val["name"] = token;
|
|
1175
1217
|
token = this.tn.next();
|
|
1176
1218
|
if (token !== Lang.EQUAL)
|
|
1177
|
-
throw Error("Illegal
|
|
1219
|
+
throw Error("Illegal token in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
1178
1220
|
token = this.tn.next();
|
|
1179
1221
|
try {
|
|
1180
1222
|
val["id"] = this._parseId(token, true);
|
|
1181
1223
|
} catch (e) {
|
|
1182
|
-
throw Error("Illegal
|
|
1224
|
+
throw Error("Illegal id in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
1183
1225
|
}
|
|
1184
1226
|
enm["values"].push(val);
|
|
1185
1227
|
token = this.tn.next();
|
|
@@ -1189,7 +1231,7 @@
|
|
|
1189
1231
|
token = this.tn.next();
|
|
1190
1232
|
}
|
|
1191
1233
|
if (token !== Lang.END)
|
|
1192
|
-
throw Error("Illegal
|
|
1234
|
+
throw Error("Illegal delimiter in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
1193
1235
|
};
|
|
1194
1236
|
|
|
1195
1237
|
/**
|
|
@@ -1199,7 +1241,7 @@
|
|
|
1199
1241
|
* @throws {Error} If the extensions statement cannot be parsed
|
|
1200
1242
|
* @private
|
|
1201
1243
|
*/
|
|
1202
|
-
|
|
1244
|
+
ParserPrototype._parseExtensions = function(msg, token) {
|
|
1203
1245
|
/** @type {Array.<number>} */
|
|
1204
1246
|
var range = [];
|
|
1205
1247
|
token = this.tn.next();
|
|
@@ -1211,7 +1253,7 @@
|
|
|
1211
1253
|
range.push(this._parseNumber(token));
|
|
1212
1254
|
token = this.tn.next();
|
|
1213
1255
|
if (token !== 'to')
|
|
1214
|
-
throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+"
|
|
1256
|
+
throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
1215
1257
|
token = this.tn.next();
|
|
1216
1258
|
if (token === "min")
|
|
1217
1259
|
range.push(ProtoBuf.ID_MIN);
|
|
@@ -1221,7 +1263,7 @@
|
|
|
1221
1263
|
range.push(this._parseNumber(token));
|
|
1222
1264
|
token = this.tn.next();
|
|
1223
1265
|
if (token !== Lang.END)
|
|
1224
|
-
throw Error("Illegal
|
|
1266
|
+
throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
1225
1267
|
return range;
|
|
1226
1268
|
};
|
|
1227
1269
|
|
|
@@ -1232,17 +1274,17 @@
|
|
|
1232
1274
|
* @throws {Error} If the extend block cannot be parsed
|
|
1233
1275
|
* @private
|
|
1234
1276
|
*/
|
|
1235
|
-
|
|
1277
|
+
ParserPrototype._parseExtend = function(parent, token) {
|
|
1236
1278
|
token = this.tn.next();
|
|
1237
1279
|
if (!Lang.TYPEREF.test(token))
|
|
1238
|
-
throw Error("Illegal
|
|
1280
|
+
throw Error("Illegal message name at line "+this.tn.line+": "+token);
|
|
1239
1281
|
/** @dict */
|
|
1240
1282
|
var ext = {};
|
|
1241
1283
|
ext["ref"] = token;
|
|
1242
1284
|
ext["fields"] = [];
|
|
1243
1285
|
token = this.tn.next();
|
|
1244
1286
|
if (token !== Lang.OPEN)
|
|
1245
|
-
throw Error("Illegal
|
|
1287
|
+
throw Error("Illegal start of extend "+ext.name+" at line "+this.tn.line+": "+token);
|
|
1246
1288
|
do {
|
|
1247
1289
|
token = this.tn.next();
|
|
1248
1290
|
if (token === Lang.CLOSE) {
|
|
@@ -1253,7 +1295,7 @@
|
|
|
1253
1295
|
} else if (Lang.RULE.test(token))
|
|
1254
1296
|
this._parseMessageField(ext, token);
|
|
1255
1297
|
else
|
|
1256
|
-
throw Error("Illegal token in extend "+ext.name+" at line "+this.tn.line+": "+token
|
|
1298
|
+
throw Error("Illegal token in extend "+ext.name+" at line "+this.tn.line+": "+token);
|
|
1257
1299
|
} while (true);
|
|
1258
1300
|
parent["messages"].push(ext);
|
|
1259
1301
|
return ext;
|
|
@@ -1263,7 +1305,7 @@
|
|
|
1263
1305
|
* Returns a string representation of this object.
|
|
1264
1306
|
* @returns {string} String representation as of "Parser"
|
|
1265
1307
|
*/
|
|
1266
|
-
|
|
1308
|
+
ParserPrototype.toString = function() {
|
|
1267
1309
|
return "Parser";
|
|
1268
1310
|
};
|
|
1269
1311
|
|
|
@@ -1296,14 +1338,22 @@
|
|
|
1296
1338
|
* @exports ProtoBuf.Reflect.T
|
|
1297
1339
|
* @constructor
|
|
1298
1340
|
* @abstract
|
|
1299
|
-
* @param {ProtoBuf.
|
|
1341
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
1342
|
+
* @param {?ProtoBuf.Reflect.T} parent Parent object
|
|
1300
1343
|
* @param {string} name Object name
|
|
1301
1344
|
*/
|
|
1302
|
-
var T = function(parent, name) {
|
|
1345
|
+
var T = function(builder, parent, name) {
|
|
1346
|
+
|
|
1347
|
+
/**
|
|
1348
|
+
* Builder reference.
|
|
1349
|
+
* @type {!ProtoBuf.Builder}
|
|
1350
|
+
* @expose
|
|
1351
|
+
*/
|
|
1352
|
+
this.builder = builder;
|
|
1303
1353
|
|
|
1304
1354
|
/**
|
|
1305
1355
|
* Parent object.
|
|
1306
|
-
* @type {ProtoBuf.Reflect.T
|
|
1356
|
+
* @type {?ProtoBuf.Reflect.T}
|
|
1307
1357
|
* @expose
|
|
1308
1358
|
*/
|
|
1309
1359
|
this.parent = parent;
|
|
@@ -1323,12 +1373,18 @@
|
|
|
1323
1373
|
this.className;
|
|
1324
1374
|
};
|
|
1325
1375
|
|
|
1376
|
+
/**
|
|
1377
|
+
* @alias ProtoBuf.Reflect.T.prototype
|
|
1378
|
+
* @inner
|
|
1379
|
+
*/
|
|
1380
|
+
var TPrototype = T.prototype;
|
|
1381
|
+
|
|
1326
1382
|
/**
|
|
1327
1383
|
* Returns the fully qualified name of this object.
|
|
1328
1384
|
* @returns {string} Fully qualified name as of ".PATH.TO.THIS"
|
|
1329
1385
|
* @expose
|
|
1330
1386
|
*/
|
|
1331
|
-
|
|
1387
|
+
TPrototype.fqn = function() {
|
|
1332
1388
|
var name = this.name,
|
|
1333
1389
|
ptr = this;
|
|
1334
1390
|
do {
|
|
@@ -1346,7 +1402,7 @@
|
|
|
1346
1402
|
* @return String representation
|
|
1347
1403
|
* @expose
|
|
1348
1404
|
*/
|
|
1349
|
-
|
|
1405
|
+
TPrototype.toString = function(includeClass) {
|
|
1350
1406
|
return (includeClass ? this.className + " " : "") + this.fqn();
|
|
1351
1407
|
};
|
|
1352
1408
|
|
|
@@ -1355,7 +1411,7 @@
|
|
|
1355
1411
|
* @throws {Error} If this type cannot be built directly
|
|
1356
1412
|
* @expose
|
|
1357
1413
|
*/
|
|
1358
|
-
|
|
1414
|
+
TPrototype.build = function() {
|
|
1359
1415
|
throw Error(this.toString(true)+" cannot be built directly");
|
|
1360
1416
|
};
|
|
1361
1417
|
|
|
@@ -1368,14 +1424,15 @@
|
|
|
1368
1424
|
/**
|
|
1369
1425
|
* Constructs a new Namespace.
|
|
1370
1426
|
* @exports ProtoBuf.Reflect.Namespace
|
|
1371
|
-
* @param {ProtoBuf.
|
|
1427
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
1428
|
+
* @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
|
|
1372
1429
|
* @param {string} name Namespace name
|
|
1373
|
-
* @param {Object.<string
|
|
1430
|
+
* @param {Object.<string,*>=} options Namespace options
|
|
1374
1431
|
* @constructor
|
|
1375
1432
|
* @extends ProtoBuf.Reflect.T
|
|
1376
1433
|
*/
|
|
1377
|
-
var Namespace = function(parent, name, options) {
|
|
1378
|
-
T.call(this, parent, name);
|
|
1434
|
+
var Namespace = function(builder, parent, name, options) {
|
|
1435
|
+
T.call(this, builder, parent, name);
|
|
1379
1436
|
|
|
1380
1437
|
/**
|
|
1381
1438
|
* @override
|
|
@@ -1384,19 +1441,22 @@
|
|
|
1384
1441
|
|
|
1385
1442
|
/**
|
|
1386
1443
|
* Children inside the namespace.
|
|
1387
|
-
* @type {Array.<ProtoBuf.Reflect.T>}
|
|
1444
|
+
* @type {!Array.<ProtoBuf.Reflect.T>}
|
|
1388
1445
|
*/
|
|
1389
1446
|
this.children = [];
|
|
1390
1447
|
|
|
1391
1448
|
/**
|
|
1392
1449
|
* Options.
|
|
1393
|
-
* @type {Object.<string, *>}
|
|
1450
|
+
* @type {!Object.<string, *>}
|
|
1394
1451
|
*/
|
|
1395
1452
|
this.options = options || {};
|
|
1396
1453
|
};
|
|
1397
1454
|
|
|
1398
|
-
|
|
1399
|
-
|
|
1455
|
+
/**
|
|
1456
|
+
* @alias ProtoBuf.Reflect.Namespace.prototype
|
|
1457
|
+
* @inner
|
|
1458
|
+
*/
|
|
1459
|
+
var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
|
|
1400
1460
|
|
|
1401
1461
|
/**
|
|
1402
1462
|
* Returns an array of the namespace's children.
|
|
@@ -1404,7 +1464,7 @@
|
|
|
1404
1464
|
* @return {Array.<ProtoBuf.Reflect.T>}
|
|
1405
1465
|
* @expose
|
|
1406
1466
|
*/
|
|
1407
|
-
|
|
1467
|
+
NamespacePrototype.getChildren = function(type) {
|
|
1408
1468
|
type = type || null;
|
|
1409
1469
|
if (type == null)
|
|
1410
1470
|
return this.children.slice();
|
|
@@ -1421,7 +1481,7 @@
|
|
|
1421
1481
|
* @throws {Error} If the child cannot be added (duplicate)
|
|
1422
1482
|
* @expose
|
|
1423
1483
|
*/
|
|
1424
|
-
|
|
1484
|
+
NamespacePrototype.addChild = function(child) {
|
|
1425
1485
|
var other;
|
|
1426
1486
|
if (other = this.getChild(child.name)) {
|
|
1427
1487
|
// Try to revert camelcase transformation on collision
|
|
@@ -1441,7 +1501,7 @@
|
|
|
1441
1501
|
* @return {?ProtoBuf.Reflect.T} The child or null if not found
|
|
1442
1502
|
* @expose
|
|
1443
1503
|
*/
|
|
1444
|
-
|
|
1504
|
+
NamespacePrototype.getChild = function(nameOrId) {
|
|
1445
1505
|
var key = typeof nameOrId === 'number' ? 'id' : 'name';
|
|
1446
1506
|
for (var i=0, k=this.children.length; i<k; ++i)
|
|
1447
1507
|
if (this.children[i][key] === nameOrId)
|
|
@@ -1456,7 +1516,7 @@
|
|
|
1456
1516
|
* @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
|
|
1457
1517
|
* @expose
|
|
1458
1518
|
*/
|
|
1459
|
-
|
|
1519
|
+
NamespacePrototype.resolve = function(qn, excludeFields) {
|
|
1460
1520
|
var part = qn.split("."),
|
|
1461
1521
|
ptr = this,
|
|
1462
1522
|
i = 0;
|
|
@@ -1490,7 +1550,7 @@
|
|
|
1490
1550
|
* @return {Object.<string,Function|Object>} Runtime namespace
|
|
1491
1551
|
* @expose
|
|
1492
1552
|
*/
|
|
1493
|
-
|
|
1553
|
+
NamespacePrototype.build = function() {
|
|
1494
1554
|
/** @dict */
|
|
1495
1555
|
var ns = {};
|
|
1496
1556
|
var children = this.children;
|
|
@@ -1508,7 +1568,7 @@
|
|
|
1508
1568
|
* Builds the namespace's '$options' property.
|
|
1509
1569
|
* @return {Object.<string,*>}
|
|
1510
1570
|
*/
|
|
1511
|
-
|
|
1571
|
+
NamespacePrototype.buildOpt = function() {
|
|
1512
1572
|
var opt = {},
|
|
1513
1573
|
keys = Object.keys(this.options);
|
|
1514
1574
|
for (var i=0, k=keys.length; i<k; ++i) {
|
|
@@ -1529,7 +1589,7 @@
|
|
|
1529
1589
|
* @param {string=} name Returns the option value if specified, otherwise all options are returned.
|
|
1530
1590
|
* @return {*|Object.<string,*>}null} Option value or NULL if there is no such option
|
|
1531
1591
|
*/
|
|
1532
|
-
|
|
1592
|
+
NamespacePrototype.getOption = function(name) {
|
|
1533
1593
|
if (typeof name === 'undefined')
|
|
1534
1594
|
return this.options;
|
|
1535
1595
|
return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
|
|
@@ -1544,15 +1604,16 @@
|
|
|
1544
1604
|
/**
|
|
1545
1605
|
* Constructs a new Message.
|
|
1546
1606
|
* @exports ProtoBuf.Reflect.Message
|
|
1547
|
-
* @param {ProtoBuf.
|
|
1607
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
1608
|
+
* @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
|
|
1548
1609
|
* @param {string} name Message name
|
|
1549
|
-
* @param {Object.<string
|
|
1610
|
+
* @param {Object.<string,*>=} options Message options
|
|
1550
1611
|
* @param {boolean=} isGroup `true` if this is a legacy group
|
|
1551
1612
|
* @constructor
|
|
1552
1613
|
* @extends ProtoBuf.Reflect.Namespace
|
|
1553
1614
|
*/
|
|
1554
|
-
var Message = function(parent, name, options, isGroup) {
|
|
1555
|
-
Namespace.call(this, parent, name, options);
|
|
1615
|
+
var Message = function(builder, parent, name, options, isGroup) {
|
|
1616
|
+
Namespace.call(this, builder, parent, name, options);
|
|
1556
1617
|
|
|
1557
1618
|
/**
|
|
1558
1619
|
* @override
|
|
@@ -1595,10 +1656,20 @@
|
|
|
1595
1656
|
* @private
|
|
1596
1657
|
*/
|
|
1597
1658
|
this._fieldsById = null;
|
|
1659
|
+
|
|
1660
|
+
/**
|
|
1661
|
+
* Cached fields by name.
|
|
1662
|
+
* @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}
|
|
1663
|
+
* @private
|
|
1664
|
+
*/
|
|
1665
|
+
this._fieldsByName = null;
|
|
1598
1666
|
};
|
|
1599
1667
|
|
|
1600
|
-
|
|
1601
|
-
|
|
1668
|
+
/**
|
|
1669
|
+
* @alias ProtoBuf.Reflect.Message.prototype
|
|
1670
|
+
* @inner
|
|
1671
|
+
*/
|
|
1672
|
+
var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
|
|
1602
1673
|
|
|
1603
1674
|
/**
|
|
1604
1675
|
* Builds the message and returns the runtime counterpart, which is a fully functional class.
|
|
@@ -1608,14 +1679,15 @@
|
|
|
1608
1679
|
* @throws {Error} If the message cannot be built
|
|
1609
1680
|
* @expose
|
|
1610
1681
|
*/
|
|
1611
|
-
|
|
1682
|
+
MessagePrototype.build = function(rebuild) {
|
|
1612
1683
|
if (this.clazz && !rebuild)
|
|
1613
1684
|
return this.clazz;
|
|
1614
1685
|
|
|
1615
1686
|
// Create the runtime Message class in its own scope
|
|
1616
1687
|
var clazz = (function(ProtoBuf, T) {
|
|
1617
1688
|
|
|
1618
|
-
var fields = T.getChildren(ProtoBuf.Reflect.Message.Field)
|
|
1689
|
+
var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
|
|
1690
|
+
oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
|
|
1619
1691
|
|
|
1620
1692
|
/**
|
|
1621
1693
|
* Constructs a new runtime Message.
|
|
@@ -1629,9 +1701,13 @@
|
|
|
1629
1701
|
var Message = function(values, var_args) {
|
|
1630
1702
|
ProtoBuf.Builder.Message.call(this);
|
|
1631
1703
|
|
|
1632
|
-
// Create
|
|
1633
|
-
for (var i=0, k=
|
|
1634
|
-
this[
|
|
1704
|
+
// Create virtual oneof properties
|
|
1705
|
+
for (var i=0, k=oneofs.length; i<k; ++i)
|
|
1706
|
+
this[oneofs[i].name] = null;
|
|
1707
|
+
// Create fields and set default values
|
|
1708
|
+
for (i=0, k=fields.length; i<k; ++i) {
|
|
1709
|
+
var field = fields[i];
|
|
1710
|
+
this[field.name] = field.repeated ? [] : null;
|
|
1635
1711
|
if (field.required && field.defaultValue !== null)
|
|
1636
1712
|
this[field.name] = field.defaultValue;
|
|
1637
1713
|
}
|
|
@@ -1647,21 +1723,17 @@
|
|
|
1647
1723
|
var keys = Object.keys(values);
|
|
1648
1724
|
for (i=0, k=keys.length; i<k; ++i)
|
|
1649
1725
|
this.$set(keys[i], values[keys[i]]); // May throw
|
|
1650
|
-
} else //
|
|
1726
|
+
} else // Set field values from arguments, in declaration order
|
|
1651
1727
|
for (i=0, k=arguments.length; i<k; ++i)
|
|
1652
1728
|
this.$set(fields[i].name, arguments[i]); // May throw
|
|
1653
1729
|
}
|
|
1654
1730
|
};
|
|
1655
1731
|
|
|
1656
1732
|
/**
|
|
1657
|
-
*
|
|
1658
|
-
* @
|
|
1659
|
-
* @type {!ProtoBuf.Reflect.Message}
|
|
1660
|
-
* @expose
|
|
1733
|
+
* @alias ProtoBuf.Builder.Message.prototype
|
|
1734
|
+
* @inner
|
|
1661
1735
|
*/
|
|
1662
|
-
|
|
1663
|
-
// Extends ProtoBuf.Builder.Message
|
|
1664
|
-
Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
|
|
1736
|
+
var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
|
|
1665
1737
|
|
|
1666
1738
|
/**
|
|
1667
1739
|
* Adds a value to a repeated field.
|
|
@@ -1673,14 +1745,16 @@
|
|
|
1673
1745
|
* @throws {Error} If the value cannot be added
|
|
1674
1746
|
* @expose
|
|
1675
1747
|
*/
|
|
1676
|
-
|
|
1677
|
-
var field = T.
|
|
1678
|
-
if (!
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1748
|
+
MessagePrototype.add = function(key, value, noAssert) {
|
|
1749
|
+
var field = T._fieldsByName[key];
|
|
1750
|
+
if (!noAssert) {
|
|
1751
|
+
if (!field)
|
|
1752
|
+
throw Error(this+"#"+key+" is undefined");
|
|
1753
|
+
if (!(field instanceof ProtoBuf.Reflect.Message.Field))
|
|
1754
|
+
throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
|
|
1755
|
+
if (!field.repeated)
|
|
1756
|
+
throw Error(this+"#"+key+" is not a repeated field");
|
|
1757
|
+
}
|
|
1684
1758
|
if (this[field.name] === null)
|
|
1685
1759
|
this[field.name] = [];
|
|
1686
1760
|
this[field.name].push(noAssert ? value : field.verifyValue(value, true));
|
|
@@ -1696,7 +1770,7 @@
|
|
|
1696
1770
|
* @throws {Error} If the value cannot be added
|
|
1697
1771
|
* @expose
|
|
1698
1772
|
*/
|
|
1699
|
-
|
|
1773
|
+
MessagePrototype.$add = MessagePrototype.add;
|
|
1700
1774
|
|
|
1701
1775
|
/**
|
|
1702
1776
|
* Sets a field's value.
|
|
@@ -1709,23 +1783,31 @@
|
|
|
1709
1783
|
* @throws {Error} If the value cannot be set
|
|
1710
1784
|
* @expose
|
|
1711
1785
|
*/
|
|
1712
|
-
|
|
1786
|
+
MessagePrototype.set = function(key, value, noAssert) {
|
|
1713
1787
|
if (key && typeof key === 'object') {
|
|
1714
1788
|
for (var i in key)
|
|
1715
1789
|
if (key.hasOwnProperty(i))
|
|
1716
1790
|
this.$set(i, key[i], noAssert);
|
|
1717
1791
|
return this;
|
|
1718
1792
|
}
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1793
|
+
var field = T._fieldsByName[key];
|
|
1794
|
+
if (!noAssert) {
|
|
1795
|
+
if (!field)
|
|
1796
|
+
throw Error(this+"#"+key+" is not a field: undefined");
|
|
1797
|
+
if (!(field instanceof ProtoBuf.Reflect.Message.Field))
|
|
1798
|
+
throw Error(this+"#"+key+" is not a field: "+field.toString(true));
|
|
1799
|
+
this[field.name] = (value = field.verifyValue(value)); // May throw
|
|
1800
|
+
} else {
|
|
1801
|
+
this[field.name] = value;
|
|
1802
|
+
}
|
|
1803
|
+
if (field.oneof) {
|
|
1804
|
+
if (value !== null) {
|
|
1805
|
+
if (this[field.oneof.name] !== null)
|
|
1806
|
+
this[this[field.oneof.name]] = null; // Unset the previous (field name is the oneof field's value)
|
|
1807
|
+
this[field.oneof.name] = field.name;
|
|
1808
|
+
} else if (field.oneof.name === key)
|
|
1809
|
+
this[field.oneof.name] = null;
|
|
1722
1810
|
}
|
|
1723
|
-
var field = T.getChild(key);
|
|
1724
|
-
if (!field)
|
|
1725
|
-
throw Error(this+"#"+key+" is not a field: undefined");
|
|
1726
|
-
if (!(field instanceof ProtoBuf.Reflect.Message.Field))
|
|
1727
|
-
throw Error(this+"#"+key+" is not a field: "+field.toString(true));
|
|
1728
|
-
this[field.name] = field.verifyValue(value); // May throw
|
|
1729
1811
|
return this;
|
|
1730
1812
|
};
|
|
1731
1813
|
|
|
@@ -1735,26 +1817,26 @@
|
|
|
1735
1817
|
* @function
|
|
1736
1818
|
* @param {string} key Key
|
|
1737
1819
|
* @param {*} value Value to set
|
|
1738
|
-
* @param {boolean=} noAssert Whether to assert the value
|
|
1820
|
+
* @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
|
|
1739
1821
|
* @throws {Error} If the value cannot be set
|
|
1740
1822
|
* @expose
|
|
1741
1823
|
*/
|
|
1742
|
-
|
|
1824
|
+
MessagePrototype.$set = MessagePrototype.set;
|
|
1743
1825
|
|
|
1744
1826
|
/**
|
|
1745
1827
|
* Gets a field's value.
|
|
1746
1828
|
* @name ProtoBuf.Builder.Message#get
|
|
1747
1829
|
* @function
|
|
1748
1830
|
* @param {string} key Key
|
|
1749
|
-
* @param {boolean=} noAssert Whether to
|
|
1831
|
+
* @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
|
|
1750
1832
|
* @return {*} Value
|
|
1751
1833
|
* @throws {Error} If there is no such field
|
|
1752
1834
|
* @expose
|
|
1753
1835
|
*/
|
|
1754
|
-
|
|
1836
|
+
MessagePrototype.get = function(key, noAssert) {
|
|
1755
1837
|
if (noAssert)
|
|
1756
1838
|
return this[key];
|
|
1757
|
-
var field = T.
|
|
1839
|
+
var field = T._fieldsByName[key];
|
|
1758
1840
|
if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
|
|
1759
1841
|
throw Error(this+"#"+key+" is not a field: undefined");
|
|
1760
1842
|
if (!(field instanceof ProtoBuf.Reflect.Message.Field))
|
|
@@ -1771,7 +1853,7 @@
|
|
|
1771
1853
|
* @throws {Error} If there is no such field
|
|
1772
1854
|
* @expose
|
|
1773
1855
|
*/
|
|
1774
|
-
|
|
1856
|
+
MessagePrototype.$get = MessagePrototype.get;
|
|
1775
1857
|
|
|
1776
1858
|
// Getters and setters
|
|
1777
1859
|
|
|
@@ -1781,72 +1863,91 @@
|
|
|
1781
1863
|
if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
|
|
1782
1864
|
continue;
|
|
1783
1865
|
|
|
1784
|
-
if (
|
|
1866
|
+
if (T.builder.options['populateAccessors'])
|
|
1785
1867
|
(function(field) {
|
|
1786
1868
|
// set/get[SomeValue]
|
|
1787
1869
|
var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
|
|
1788
1870
|
return match.toUpperCase().replace('_','');
|
|
1789
1871
|
});
|
|
1790
|
-
Name = Name.substring(0,1).toUpperCase()+Name.substring(1);
|
|
1872
|
+
Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
|
|
1791
1873
|
|
|
1792
|
-
// set/get_[some_value]
|
|
1874
|
+
// set/get_[some_value] FIXME: Do we really need these?
|
|
1793
1875
|
var name = field.originalName.replace(/([A-Z])/g, function(match) {
|
|
1794
1876
|
return "_"+match;
|
|
1795
1877
|
});
|
|
1796
1878
|
|
|
1879
|
+
/**
|
|
1880
|
+
* The current field's unbound setter function.
|
|
1881
|
+
* @function
|
|
1882
|
+
* @param {*} value
|
|
1883
|
+
* @param {boolean=} noAssert
|
|
1884
|
+
* @returns {!ProtoBuf.Builder.Message}
|
|
1885
|
+
* @inner
|
|
1886
|
+
*/
|
|
1887
|
+
var setter = function(value, noAssert) {
|
|
1888
|
+
this[field.name] = noAssert ? value : field.verifyValue(value);
|
|
1889
|
+
return this;
|
|
1890
|
+
};
|
|
1891
|
+
|
|
1892
|
+
/**
|
|
1893
|
+
* The current field's unbound getter function.
|
|
1894
|
+
* @function
|
|
1895
|
+
* @returns {*}
|
|
1896
|
+
* @inner
|
|
1897
|
+
*/
|
|
1898
|
+
var getter = function() {
|
|
1899
|
+
return this[field.name];
|
|
1900
|
+
};
|
|
1901
|
+
|
|
1797
1902
|
/**
|
|
1798
1903
|
* Sets a value. This method is present for each field, but only if there is no name conflict with
|
|
1799
|
-
*
|
|
1904
|
+
* another field.
|
|
1800
1905
|
* @name ProtoBuf.Builder.Message#set[SomeField]
|
|
1801
1906
|
* @function
|
|
1802
1907
|
* @param {*} value Value to set
|
|
1908
|
+
* @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
|
|
1909
|
+
* @returns {!ProtoBuf.Builder.Message} this
|
|
1803
1910
|
* @abstract
|
|
1804
1911
|
* @throws {Error} If the value cannot be set
|
|
1805
1912
|
*/
|
|
1806
1913
|
if (T.getChild("set"+Name) === null)
|
|
1807
|
-
|
|
1808
|
-
this.$set(field.name, value);
|
|
1809
|
-
};
|
|
1914
|
+
MessagePrototype["set"+Name] = setter;
|
|
1810
1915
|
|
|
1811
1916
|
/**
|
|
1812
1917
|
* Sets a value. This method is present for each field, but only if there is no name conflict with
|
|
1813
|
-
*
|
|
1918
|
+
* another field.
|
|
1814
1919
|
* @name ProtoBuf.Builder.Message#set_[some_field]
|
|
1815
1920
|
* @function
|
|
1816
1921
|
* @param {*} value Value to set
|
|
1922
|
+
* @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
|
|
1923
|
+
* @returns {!ProtoBuf.Builder.Message} this
|
|
1817
1924
|
* @abstract
|
|
1818
1925
|
* @throws {Error} If the value cannot be set
|
|
1819
1926
|
*/
|
|
1820
1927
|
if (T.getChild("set_"+name) === null)
|
|
1821
|
-
|
|
1822
|
-
this.$set(field.name, value);
|
|
1823
|
-
};
|
|
1928
|
+
MessagePrototype["set_"+name] = setter;
|
|
1824
1929
|
|
|
1825
1930
|
/**
|
|
1826
1931
|
* Gets a value. This method is present for each field, but only if there is no name conflict with
|
|
1827
|
-
*
|
|
1932
|
+
* another field.
|
|
1828
1933
|
* @name ProtoBuf.Builder.Message#get[SomeField]
|
|
1829
1934
|
* @function
|
|
1830
1935
|
* @abstract
|
|
1831
1936
|
* @return {*} The value
|
|
1832
1937
|
*/
|
|
1833
1938
|
if (T.getChild("get"+Name) === null)
|
|
1834
|
-
|
|
1835
|
-
return this.$get(field.name); // Does not throw, field exists
|
|
1836
|
-
};
|
|
1939
|
+
MessagePrototype["get"+Name] = getter;
|
|
1837
1940
|
|
|
1838
1941
|
/**
|
|
1839
1942
|
* Gets a value. This method is present for each field, but only if there is no name conflict with
|
|
1840
|
-
*
|
|
1943
|
+
* another field.
|
|
1841
1944
|
* @name ProtoBuf.Builder.Message#get_[some_field]
|
|
1842
1945
|
* @function
|
|
1843
1946
|
* @return {*} The value
|
|
1844
1947
|
* @abstract
|
|
1845
1948
|
*/
|
|
1846
1949
|
if (T.getChild("get_"+name) === null)
|
|
1847
|
-
|
|
1848
|
-
return this.$get(field.name); // Does not throw, field exists
|
|
1849
|
-
};
|
|
1950
|
+
MessagePrototype["get_"+name] = getter;
|
|
1850
1951
|
|
|
1851
1952
|
})(field);
|
|
1852
1953
|
}
|
|
@@ -1867,7 +1968,7 @@
|
|
|
1867
1968
|
* @see ProtoBuf.Builder.Message#encodeHex
|
|
1868
1969
|
* @see ProtoBuf.Builder.Message#encodeAB
|
|
1869
1970
|
*/
|
|
1870
|
-
|
|
1971
|
+
MessagePrototype.encode = function(buffer, noVerify) {
|
|
1871
1972
|
if (typeof buffer === 'boolean')
|
|
1872
1973
|
noVerify = buffer,
|
|
1873
1974
|
buffer = undefined;
|
|
@@ -1893,7 +1994,7 @@
|
|
|
1893
1994
|
* @throws {Error} If the message cannot be calculated or if required fields are missing.
|
|
1894
1995
|
* @expose
|
|
1895
1996
|
*/
|
|
1896
|
-
|
|
1997
|
+
MessagePrototype.calculate = function() {
|
|
1897
1998
|
return T.calculate(this);
|
|
1898
1999
|
};
|
|
1899
2000
|
|
|
@@ -1907,7 +2008,7 @@
|
|
|
1907
2008
|
* returns the encoded ByteBuffer in the `encoded` property on the error.
|
|
1908
2009
|
* @expose
|
|
1909
2010
|
*/
|
|
1910
|
-
|
|
2011
|
+
MessagePrototype.encodeDelimited = function(buffer) {
|
|
1911
2012
|
var isNew = false;
|
|
1912
2013
|
if (!buffer)
|
|
1913
2014
|
buffer = new ByteBuffer(),
|
|
@@ -1928,7 +2029,7 @@
|
|
|
1928
2029
|
* returns the encoded ArrayBuffer in the `encoded` property on the error.
|
|
1929
2030
|
* @expose
|
|
1930
2031
|
*/
|
|
1931
|
-
|
|
2032
|
+
MessagePrototype.encodeAB = function() {
|
|
1932
2033
|
try {
|
|
1933
2034
|
return this.encode().toArrayBuffer();
|
|
1934
2035
|
} catch (e) {
|
|
@@ -1946,7 +2047,7 @@
|
|
|
1946
2047
|
* returns the encoded ArrayBuffer in the `encoded` property on the error.
|
|
1947
2048
|
* @expose
|
|
1948
2049
|
*/
|
|
1949
|
-
|
|
2050
|
+
MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
|
|
1950
2051
|
|
|
1951
2052
|
/**
|
|
1952
2053
|
* Directly encodes the message to a node Buffer.
|
|
@@ -1957,7 +2058,7 @@
|
|
|
1957
2058
|
* missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
|
|
1958
2059
|
* @expose
|
|
1959
2060
|
*/
|
|
1960
|
-
|
|
2061
|
+
MessagePrototype.encodeNB = function() {
|
|
1961
2062
|
try {
|
|
1962
2063
|
return this.encode().toBuffer();
|
|
1963
2064
|
} catch (e) {
|
|
@@ -1975,7 +2076,7 @@
|
|
|
1975
2076
|
* returns the encoded node Buffer in the `encoded` property on the error.
|
|
1976
2077
|
* @expose
|
|
1977
2078
|
*/
|
|
1978
|
-
|
|
2079
|
+
MessagePrototype.toBuffer = MessagePrototype.encodeNB;
|
|
1979
2080
|
|
|
1980
2081
|
/**
|
|
1981
2082
|
* Directly encodes the message to a base64 encoded string.
|
|
@@ -1986,7 +2087,7 @@
|
|
|
1986
2087
|
* still returns the encoded base64 string in the `encoded` property on the error.
|
|
1987
2088
|
* @expose
|
|
1988
2089
|
*/
|
|
1989
|
-
|
|
2090
|
+
MessagePrototype.encode64 = function() {
|
|
1990
2091
|
try {
|
|
1991
2092
|
return this.encode().toBase64();
|
|
1992
2093
|
} catch (e) {
|
|
@@ -2004,7 +2105,7 @@
|
|
|
2004
2105
|
* returns the encoded base64 string in the `encoded` property on the error.
|
|
2005
2106
|
* @expose
|
|
2006
2107
|
*/
|
|
2007
|
-
|
|
2108
|
+
MessagePrototype.toBase64 = MessagePrototype.encode64;
|
|
2008
2109
|
|
|
2009
2110
|
/**
|
|
2010
2111
|
* Directly encodes the message to a hex encoded string.
|
|
@@ -2015,7 +2116,7 @@
|
|
|
2015
2116
|
* still returns the encoded hex string in the `encoded` property on the error.
|
|
2016
2117
|
* @expose
|
|
2017
2118
|
*/
|
|
2018
|
-
|
|
2119
|
+
MessagePrototype.encodeHex = function() {
|
|
2019
2120
|
try {
|
|
2020
2121
|
return this.encode().toHex();
|
|
2021
2122
|
} catch (e) {
|
|
@@ -2033,38 +2134,38 @@
|
|
|
2033
2134
|
* returns the encoded hex string in the `encoded` property on the error.
|
|
2034
2135
|
* @expose
|
|
2035
2136
|
*/
|
|
2036
|
-
|
|
2137
|
+
MessagePrototype.toHex = MessagePrototype.encodeHex;
|
|
2037
2138
|
|
|
2038
2139
|
/**
|
|
2039
2140
|
* Clones a message object to a raw object.
|
|
2040
2141
|
* @param {*} obj Object to clone
|
|
2041
|
-
* @param {boolean}
|
|
2142
|
+
* @param {boolean} includeBinaryAsBase64 Whether to include binary data as base64 strings or not
|
|
2042
2143
|
* @returns {*} Cloned object
|
|
2043
2144
|
* @inner
|
|
2044
2145
|
*/
|
|
2045
|
-
function cloneRaw(obj,
|
|
2146
|
+
function cloneRaw(obj, includeBinaryAsBase64) {
|
|
2046
2147
|
var clone = {};
|
|
2047
2148
|
for (var i in obj)
|
|
2048
2149
|
if (obj.hasOwnProperty(i)) {
|
|
2049
2150
|
if (obj[i] === null || typeof obj[i] !== 'object')
|
|
2050
2151
|
clone[i] = obj[i];
|
|
2051
2152
|
else if (obj[i] instanceof ByteBuffer) {
|
|
2052
|
-
if (
|
|
2053
|
-
clone[i] = obj.
|
|
2153
|
+
if (includeBinaryAsBase64)
|
|
2154
|
+
clone[i] = obj[i].toBase64();
|
|
2054
2155
|
} else // is a non-null object
|
|
2055
|
-
clone[i] = cloneRaw(obj[i],
|
|
2156
|
+
clone[i] = cloneRaw(obj[i], includeBinaryAsBase64);
|
|
2056
2157
|
}
|
|
2057
2158
|
return clone;
|
|
2058
2159
|
}
|
|
2059
2160
|
|
|
2060
2161
|
/**
|
|
2061
2162
|
* Returns the message's raw payload.
|
|
2062
|
-
* @param {boolean=}
|
|
2163
|
+
* @param {boolean=} includeBinaryAsBase64 Whether to include binary data as base64 strings or not, defaults to `false`
|
|
2063
2164
|
* @returns {Object.<string,*>} Raw payload
|
|
2064
2165
|
* @expose
|
|
2065
2166
|
*/
|
|
2066
|
-
|
|
2067
|
-
return cloneRaw(this, !!
|
|
2167
|
+
MessagePrototype.toRaw = function(includeBinaryAsBase64) {
|
|
2168
|
+
return cloneRaw(this, !!includeBinaryAsBase64);
|
|
2068
2169
|
};
|
|
2069
2170
|
|
|
2070
2171
|
/**
|
|
@@ -2165,7 +2266,7 @@
|
|
|
2165
2266
|
* @return {string} String representation as of ".Fully.Qualified.MessageName"
|
|
2166
2267
|
* @expose
|
|
2167
2268
|
*/
|
|
2168
|
-
|
|
2269
|
+
MessagePrototype.toString = function() {
|
|
2169
2270
|
return T.toString();
|
|
2170
2271
|
};
|
|
2171
2272
|
|
|
@@ -2189,7 +2290,7 @@
|
|
|
2189
2290
|
|
|
2190
2291
|
if (Object.defineProperty)
|
|
2191
2292
|
Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
|
|
2192
|
-
Object.defineProperty(
|
|
2293
|
+
Object.defineProperty(MessagePrototype, "$type", {
|
|
2193
2294
|
get: function() { return T; }
|
|
2194
2295
|
});
|
|
2195
2296
|
|
|
@@ -2199,20 +2300,20 @@
|
|
|
2199
2300
|
|
|
2200
2301
|
// Static enums and prototyped sub-messages / cached collections
|
|
2201
2302
|
this._fields = [];
|
|
2202
|
-
this._fieldsById =
|
|
2303
|
+
this._fieldsById = {};
|
|
2304
|
+
this._fieldsByName = {};
|
|
2203
2305
|
for (var i=0, k=this.children.length, child; i<k; i++) {
|
|
2204
2306
|
child = this.children[i];
|
|
2205
2307
|
if (child instanceof Enum)
|
|
2206
|
-
clazz[child
|
|
2308
|
+
clazz[child.name] = child.build();
|
|
2207
2309
|
else if (child instanceof Message)
|
|
2208
|
-
clazz[child
|
|
2310
|
+
clazz[child.name] = child.build();
|
|
2209
2311
|
else if (child instanceof Message.Field)
|
|
2210
2312
|
child.build(),
|
|
2211
2313
|
this._fields.push(child),
|
|
2212
|
-
this._fieldsById[child.id] = child
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
} else
|
|
2314
|
+
this._fieldsById[child.id] = child,
|
|
2315
|
+
this._fieldsByName[child.name] = child;
|
|
2316
|
+
else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built
|
|
2216
2317
|
throw Error("Illegal reflect child of "+this.toString(true)+": "+children[i].toString(true));
|
|
2217
2318
|
}
|
|
2218
2319
|
|
|
@@ -2228,11 +2329,11 @@
|
|
|
2228
2329
|
* @throws {Error} If required fields are missing or the message cannot be encoded for another reason
|
|
2229
2330
|
* @expose
|
|
2230
2331
|
*/
|
|
2231
|
-
|
|
2332
|
+
MessagePrototype.encode = function(message, buffer, noVerify) {
|
|
2232
2333
|
var fieldMissing = null,
|
|
2233
2334
|
field;
|
|
2234
2335
|
for (var i=0, k=this._fields.length, val; i<k; ++i) {
|
|
2235
|
-
field = this.
|
|
2336
|
+
field = this._fields[i];
|
|
2236
2337
|
val = message[field.name];
|
|
2237
2338
|
if (field.required && val === null) {
|
|
2238
2339
|
if (fieldMissing === null)
|
|
@@ -2255,7 +2356,7 @@
|
|
|
2255
2356
|
* @throws {Error} If required fields are missing or the message cannot be calculated for another reason
|
|
2256
2357
|
* @expose
|
|
2257
2358
|
*/
|
|
2258
|
-
|
|
2359
|
+
MessagePrototype.calculate = function(message) {
|
|
2259
2360
|
for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {
|
|
2260
2361
|
field = this._fields[i];
|
|
2261
2362
|
val = message[field.name];
|
|
@@ -2317,7 +2418,7 @@
|
|
|
2317
2418
|
* @throws {Error} If the message cannot be decoded
|
|
2318
2419
|
* @expose
|
|
2319
2420
|
*/
|
|
2320
|
-
|
|
2421
|
+
MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
|
|
2321
2422
|
length = typeof length === 'number' ? length : -1;
|
|
2322
2423
|
var start = buffer.offset,
|
|
2323
2424
|
msg = new (this.clazz)(),
|
|
@@ -2357,8 +2458,14 @@
|
|
|
2357
2458
|
}
|
|
2358
2459
|
if (field.repeated && !field.options["packed"])
|
|
2359
2460
|
msg[field.name].push(field.decode(wireType, buffer));
|
|
2360
|
-
else
|
|
2461
|
+
else {
|
|
2361
2462
|
msg[field.name] = field.decode(wireType, buffer);
|
|
2463
|
+
if (field.oneof) {
|
|
2464
|
+
if (this[field.oneof.name] !== null)
|
|
2465
|
+
this[this[field.oneof.name]] = null;
|
|
2466
|
+
msg[field.oneof.name] = field.name;
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2362
2469
|
}
|
|
2363
2470
|
|
|
2364
2471
|
// Check if all required fields are present and set default values for optional fields that are not
|
|
@@ -2384,17 +2491,19 @@
|
|
|
2384
2491
|
/**
|
|
2385
2492
|
* Constructs a new Message Field.
|
|
2386
2493
|
* @exports ProtoBuf.Reflect.Message.Field
|
|
2387
|
-
* @param {ProtoBuf.
|
|
2494
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
2495
|
+
* @param {!ProtoBuf.Reflect.Message} message Message reference
|
|
2388
2496
|
* @param {string} rule Rule, one of requried, optional, repeated
|
|
2389
2497
|
* @param {string} type Data type, e.g. int32
|
|
2390
2498
|
* @param {string} name Field name
|
|
2391
2499
|
* @param {number} id Unique field id
|
|
2392
2500
|
* @param {Object.<string,*>=} options Options
|
|
2501
|
+
* @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
|
|
2393
2502
|
* @constructor
|
|
2394
2503
|
* @extends ProtoBuf.Reflect.T
|
|
2395
2504
|
*/
|
|
2396
|
-
var Field = function(message, rule, type, name, id, options) {
|
|
2397
|
-
T.call(this, message, name);
|
|
2505
|
+
var Field = function(builder, message, rule, type, name, id, options, oneof) {
|
|
2506
|
+
T.call(this, builder, message, name);
|
|
2398
2507
|
|
|
2399
2508
|
/**
|
|
2400
2509
|
* @override
|
|
@@ -2451,6 +2560,13 @@
|
|
|
2451
2560
|
*/
|
|
2452
2561
|
this.defaultValue = null;
|
|
2453
2562
|
|
|
2563
|
+
/**
|
|
2564
|
+
* Enclosing OneOf.
|
|
2565
|
+
* @type {?ProtoBuf.Reflect.Message.OneOf}
|
|
2566
|
+
* @expose
|
|
2567
|
+
*/
|
|
2568
|
+
this.oneof = oneof || null;
|
|
2569
|
+
|
|
2454
2570
|
/**
|
|
2455
2571
|
* Original field name.
|
|
2456
2572
|
* @type {string}
|
|
@@ -2459,22 +2575,34 @@
|
|
|
2459
2575
|
this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
|
|
2460
2576
|
|
|
2461
2577
|
// Convert field names to camel case notation if the override is set
|
|
2462
|
-
if (
|
|
2463
|
-
this.name = this.name
|
|
2464
|
-
return $1.toUpperCase();
|
|
2465
|
-
});
|
|
2466
|
-
}
|
|
2578
|
+
if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))
|
|
2579
|
+
this.name = Field._toCamelCase(this.name);
|
|
2467
2580
|
};
|
|
2468
2581
|
|
|
2469
|
-
|
|
2470
|
-
|
|
2582
|
+
/**
|
|
2583
|
+
* Converts a field name to camel case.
|
|
2584
|
+
* @param {string} name Likely underscore notated name
|
|
2585
|
+
* @returns {string} Camel case notated name
|
|
2586
|
+
* @private
|
|
2587
|
+
*/
|
|
2588
|
+
Field._toCamelCase = function(name) {
|
|
2589
|
+
return name.replace(/_([a-zA-Z])/g, function($0, $1) {
|
|
2590
|
+
return $1.toUpperCase();
|
|
2591
|
+
});
|
|
2592
|
+
};
|
|
2593
|
+
|
|
2594
|
+
/**
|
|
2595
|
+
* @alias ProtoBuf.Reflect.Message.Field.prototype
|
|
2596
|
+
* @inner
|
|
2597
|
+
*/
|
|
2598
|
+
var FieldPrototype = Field.prototype = Object.create(T.prototype);
|
|
2471
2599
|
|
|
2472
2600
|
/**
|
|
2473
2601
|
* Builds the field.
|
|
2474
2602
|
* @override
|
|
2475
2603
|
* @expose
|
|
2476
2604
|
*/
|
|
2477
|
-
|
|
2605
|
+
FieldPrototype.build = function() {
|
|
2478
2606
|
this.defaultValue = typeof this.options['default'] !== 'undefined'
|
|
2479
2607
|
? this.verifyValue(this.options['default']) : null;
|
|
2480
2608
|
};
|
|
@@ -2507,7 +2635,7 @@
|
|
|
2507
2635
|
* @throws {Error} If the value cannot be set for this field
|
|
2508
2636
|
* @expose
|
|
2509
2637
|
*/
|
|
2510
|
-
|
|
2638
|
+
FieldPrototype.verifyValue = function(value, skipRepeated) {
|
|
2511
2639
|
skipRepeated = skipRepeated || false;
|
|
2512
2640
|
var fail = function(val, msg) {
|
|
2513
2641
|
throw Error("Illegal value for "+this.toString(true)+" of type "+this.type.name+": "+val+" ("+msg+")");
|
|
@@ -2595,20 +2723,18 @@
|
|
|
2595
2723
|
|
|
2596
2724
|
// Length-delimited bytes
|
|
2597
2725
|
case ProtoBuf.TYPES["bytes"]:
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2726
|
+
if (ByteBuffer.isByteBuffer(value))
|
|
2727
|
+
return value;
|
|
2728
|
+
return ByteBuffer.wrap(value, "base64");
|
|
2601
2729
|
|
|
2602
2730
|
// Constant enum value
|
|
2603
2731
|
case ProtoBuf.TYPES["enum"]: {
|
|
2604
2732
|
var values = this.resolvedType.getChildren(Enum.Value);
|
|
2605
|
-
for (i=0; i<values.length; i++)
|
|
2606
|
-
if (values[i].name == value)
|
|
2733
|
+
for (i=0; i<values.length; i++)
|
|
2734
|
+
if (values[i].name == value)
|
|
2607
2735
|
return values[i].id;
|
|
2608
|
-
|
|
2736
|
+
else if (values[i].id == value)
|
|
2609
2737
|
return values[i].id;
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2612
2738
|
fail(value, "not a valid enum value");
|
|
2613
2739
|
}
|
|
2614
2740
|
// Embedded message
|
|
@@ -2643,7 +2769,7 @@
|
|
|
2643
2769
|
* @throws {Error} If the field cannot be encoded
|
|
2644
2770
|
* @expose
|
|
2645
2771
|
*/
|
|
2646
|
-
|
|
2772
|
+
FieldPrototype.encode = function(value, buffer) {
|
|
2647
2773
|
if (this.type === null || typeof this.type !== 'object')
|
|
2648
2774
|
throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
|
|
2649
2775
|
if (value === null || (this.repeated && value.length == 0))
|
|
@@ -2695,7 +2821,7 @@
|
|
|
2695
2821
|
* @throws {Error} If the value cannot be encoded
|
|
2696
2822
|
* @expose
|
|
2697
2823
|
*/
|
|
2698
|
-
|
|
2824
|
+
FieldPrototype.encodeValue = function(value, buffer) {
|
|
2699
2825
|
if (value === null) return buffer; // Nothing to encode
|
|
2700
2826
|
// Tag has already been written
|
|
2701
2827
|
|
|
@@ -2816,7 +2942,7 @@
|
|
|
2816
2942
|
* @returns {number} Byte length
|
|
2817
2943
|
* @expose
|
|
2818
2944
|
*/
|
|
2819
|
-
|
|
2945
|
+
FieldPrototype.calculate = function(value) {
|
|
2820
2946
|
value = this.verifyValue(value); // May throw
|
|
2821
2947
|
if (this.type === null || typeof this.type !== 'object')
|
|
2822
2948
|
throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
|
|
@@ -2855,7 +2981,7 @@
|
|
|
2855
2981
|
* @throws {Error} If the value cannot be calculated
|
|
2856
2982
|
* @expose
|
|
2857
2983
|
*/
|
|
2858
|
-
|
|
2984
|
+
FieldPrototype.calculateValue = function(value) {
|
|
2859
2985
|
if (value === null) return 0; // Nothing to encode
|
|
2860
2986
|
// Tag has already been written
|
|
2861
2987
|
var n;
|
|
@@ -2911,7 +3037,7 @@
|
|
|
2911
3037
|
* @throws {Error} If the field cannot be decoded
|
|
2912
3038
|
* @expose
|
|
2913
3039
|
*/
|
|
2914
|
-
|
|
3040
|
+
FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
|
|
2915
3041
|
var value, nBytes;
|
|
2916
3042
|
if (wireType != this.type.wireType && (skipRepeated || (wireType != ProtoBuf.WIRE_TYPES.LDELIM || !this.repeated)))
|
|
2917
3043
|
throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
|
|
@@ -3011,7 +3137,7 @@
|
|
|
3011
3137
|
|
|
3012
3138
|
// We should never end here
|
|
3013
3139
|
throw Error("[INTERNAL] Illegal wire type for "+this.toString(true)+": "+wireType);
|
|
3014
|
-
}
|
|
3140
|
+
};
|
|
3015
3141
|
|
|
3016
3142
|
/**
|
|
3017
3143
|
* @alias ProtoBuf.Reflect.Message.Field
|
|
@@ -3022,7 +3148,8 @@
|
|
|
3022
3148
|
/**
|
|
3023
3149
|
* Constructs a new Message ExtensionField.
|
|
3024
3150
|
* @exports ProtoBuf.Reflect.Message.ExtensionField
|
|
3025
|
-
* @param {ProtoBuf.
|
|
3151
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3152
|
+
* @param {!ProtoBuf.Reflect.Message} message Message reference
|
|
3026
3153
|
* @param {string} rule Rule, one of requried, optional, repeated
|
|
3027
3154
|
* @param {string} type Data type, e.g. int32
|
|
3028
3155
|
* @param {string} name Field name
|
|
@@ -3031,8 +3158,8 @@
|
|
|
3031
3158
|
* @constructor
|
|
3032
3159
|
* @extends ProtoBuf.Reflect.Message.Field
|
|
3033
3160
|
*/
|
|
3034
|
-
var ExtensionField = function(message, rule, type, name, id, options) {
|
|
3035
|
-
Field.call(this, message, rule, type, name, id, options);
|
|
3161
|
+
var ExtensionField = function(builder, message, rule, type, name, id, options) {
|
|
3162
|
+
Field.call(this, builder, message, rule, type, name, id, options);
|
|
3036
3163
|
|
|
3037
3164
|
/**
|
|
3038
3165
|
* Extension reference.
|
|
@@ -3051,17 +3178,44 @@
|
|
|
3051
3178
|
*/
|
|
3052
3179
|
Reflect.Message.ExtensionField = ExtensionField;
|
|
3053
3180
|
|
|
3181
|
+
/**
|
|
3182
|
+
* Constructs a new Message OneOf.
|
|
3183
|
+
* @exports ProtoBuf.Reflect.Message.OneOf
|
|
3184
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3185
|
+
* @param {!ProtoBuf.Reflect.Message} message Message reference
|
|
3186
|
+
* @param {string} name OneOf name
|
|
3187
|
+
* @constructor
|
|
3188
|
+
* @extends ProtoBuf.Reflect.T
|
|
3189
|
+
*/
|
|
3190
|
+
var OneOf = function(builder, message, name) {
|
|
3191
|
+
T.call(this, builder, message, name);
|
|
3192
|
+
|
|
3193
|
+
/**
|
|
3194
|
+
* Enclosed fields.
|
|
3195
|
+
* @type {!Array.<!ProtoBuf.Reflect.Message.Field>}
|
|
3196
|
+
* @expose
|
|
3197
|
+
*/
|
|
3198
|
+
this.fields = [];
|
|
3199
|
+
};
|
|
3200
|
+
|
|
3201
|
+
/**
|
|
3202
|
+
* @alias ProtoBuf.Reflect.Message.OneOf
|
|
3203
|
+
* @expose
|
|
3204
|
+
*/
|
|
3205
|
+
Reflect.Message.OneOf = OneOf;
|
|
3206
|
+
|
|
3054
3207
|
/**
|
|
3055
3208
|
* Constructs a new Enum.
|
|
3056
3209
|
* @exports ProtoBuf.Reflect.Enum
|
|
3210
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3057
3211
|
* @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
|
|
3058
3212
|
* @param {string} name Enum name
|
|
3059
3213
|
* @param {Object.<string,*>=} options Enum options
|
|
3060
3214
|
* @constructor
|
|
3061
3215
|
* @extends ProtoBuf.Reflect.Namespace
|
|
3062
3216
|
*/
|
|
3063
|
-
var Enum = function(parent, name, options) {
|
|
3064
|
-
Namespace.call(this, parent, name, options);
|
|
3217
|
+
var Enum = function(builder, parent, name, options) {
|
|
3218
|
+
Namespace.call(this, builder, parent, name, options);
|
|
3065
3219
|
|
|
3066
3220
|
/**
|
|
3067
3221
|
* @override
|
|
@@ -3076,15 +3230,18 @@
|
|
|
3076
3230
|
this.object = null;
|
|
3077
3231
|
};
|
|
3078
3232
|
|
|
3079
|
-
|
|
3080
|
-
|
|
3233
|
+
/**
|
|
3234
|
+
* @alias ProtoBuf.Reflect.Enum.prototype
|
|
3235
|
+
* @inner
|
|
3236
|
+
*/
|
|
3237
|
+
var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
|
|
3081
3238
|
|
|
3082
3239
|
/**
|
|
3083
3240
|
* Builds this enum and returns the runtime counterpart.
|
|
3084
3241
|
* @return {Object<string,*>}
|
|
3085
3242
|
* @expose
|
|
3086
3243
|
*/
|
|
3087
|
-
|
|
3244
|
+
EnumPrototype.build = function() {
|
|
3088
3245
|
var enm = {},
|
|
3089
3246
|
values = this.getChildren(Enum.Value);
|
|
3090
3247
|
for (var i=0, k=values.length; i<k; ++i)
|
|
@@ -3103,14 +3260,15 @@
|
|
|
3103
3260
|
/**
|
|
3104
3261
|
* Constructs a new Enum Value.
|
|
3105
3262
|
* @exports ProtoBuf.Reflect.Enum.Value
|
|
3263
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3106
3264
|
* @param {!ProtoBuf.Reflect.Enum} enm Enum reference
|
|
3107
3265
|
* @param {string} name Field name
|
|
3108
3266
|
* @param {number} id Unique field id
|
|
3109
3267
|
* @constructor
|
|
3110
3268
|
* @extends ProtoBuf.Reflect.T
|
|
3111
3269
|
*/
|
|
3112
|
-
var Value = function(enm, name, id) {
|
|
3113
|
-
T.call(this, enm, name);
|
|
3270
|
+
var Value = function(builder, enm, name, id) {
|
|
3271
|
+
T.call(this, builder, enm, name);
|
|
3114
3272
|
|
|
3115
3273
|
/**
|
|
3116
3274
|
* @override
|
|
@@ -3138,12 +3296,13 @@
|
|
|
3138
3296
|
* An extension (field).
|
|
3139
3297
|
* @exports ProtoBuf.Reflect.Extension
|
|
3140
3298
|
* @constructor
|
|
3141
|
-
* @param {ProtoBuf.
|
|
3299
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3300
|
+
* @param {!ProtoBuf.Reflect.T} parent Parent object
|
|
3142
3301
|
* @param {string} name Object name
|
|
3143
3302
|
* @param {!ProtoBuf.Reflect.Message.Field} field Extension field
|
|
3144
3303
|
*/
|
|
3145
|
-
var Extension = function(parent, name, field) {
|
|
3146
|
-
T.call(this, parent, name);
|
|
3304
|
+
var Extension = function(builder, parent, name, field) {
|
|
3305
|
+
T.call(this, builder, parent, name);
|
|
3147
3306
|
|
|
3148
3307
|
/**
|
|
3149
3308
|
* Extended message field.
|
|
@@ -3165,14 +3324,15 @@
|
|
|
3165
3324
|
/**
|
|
3166
3325
|
* Constructs a new Service.
|
|
3167
3326
|
* @exports ProtoBuf.Reflect.Service
|
|
3327
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3168
3328
|
* @param {!ProtoBuf.Reflect.Namespace} root Root
|
|
3169
3329
|
* @param {string} name Service name
|
|
3170
3330
|
* @param {Object.<string,*>=} options Options
|
|
3171
3331
|
* @constructor
|
|
3172
3332
|
* @extends ProtoBuf.Reflect.Namespace
|
|
3173
3333
|
*/
|
|
3174
|
-
var Service = function(root, name, options) {
|
|
3175
|
-
Namespace.call(this, root, name, options);
|
|
3334
|
+
var Service = function(builder, root, name, options) {
|
|
3335
|
+
Namespace.call(this, builder, root, name, options);
|
|
3176
3336
|
|
|
3177
3337
|
/**
|
|
3178
3338
|
* @override
|
|
@@ -3186,8 +3346,11 @@
|
|
|
3186
3346
|
this.clazz = null;
|
|
3187
3347
|
};
|
|
3188
3348
|
|
|
3189
|
-
|
|
3190
|
-
|
|
3349
|
+
/**
|
|
3350
|
+
* @alias ProtoBuf.Reflect.Service.prototype
|
|
3351
|
+
* @inner
|
|
3352
|
+
*/
|
|
3353
|
+
var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
|
|
3191
3354
|
|
|
3192
3355
|
/**
|
|
3193
3356
|
* Builds the service and returns the runtime counterpart, which is a fully functional class.
|
|
@@ -3197,7 +3360,7 @@
|
|
|
3197
3360
|
* @throws {Error} If the message cannot be built
|
|
3198
3361
|
* @expose
|
|
3199
3362
|
*/
|
|
3200
|
-
|
|
3363
|
+
ServicePrototype.build = function(rebuild) {
|
|
3201
3364
|
if (this.clazz && !rebuild)
|
|
3202
3365
|
return this.clazz;
|
|
3203
3366
|
|
|
@@ -3229,12 +3392,15 @@
|
|
|
3229
3392
|
};
|
|
3230
3393
|
};
|
|
3231
3394
|
|
|
3232
|
-
|
|
3233
|
-
|
|
3395
|
+
/**
|
|
3396
|
+
* @alias ProtoBuf.Builder.Service.prototype
|
|
3397
|
+
* @inner
|
|
3398
|
+
*/
|
|
3399
|
+
var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
|
|
3234
3400
|
|
|
3235
3401
|
if (Object.defineProperty)
|
|
3236
3402
|
Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
|
|
3237
|
-
Object.defineProperty(
|
|
3403
|
+
Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] });
|
|
3238
3404
|
|
|
3239
3405
|
/**
|
|
3240
3406
|
* Asynchronously performs an RPC call using the given RPC implementation.
|
|
@@ -3262,7 +3428,7 @@
|
|
|
3262
3428
|
(function(method) {
|
|
3263
3429
|
|
|
3264
3430
|
// service#Method(message, callback)
|
|
3265
|
-
|
|
3431
|
+
ServicePrototype[method.name] = function(req, callback) {
|
|
3266
3432
|
try {
|
|
3267
3433
|
if (!req || !(req instanceof method.resolvedRequestType.clazz)) {
|
|
3268
3434
|
setTimeout(callback.bind(this, Error("Illegal request type provided to service method "+T.name+"#"+method.name)), 0);
|
|
@@ -3292,7 +3458,7 @@
|
|
|
3292
3458
|
|
|
3293
3459
|
if (Object.defineProperty)
|
|
3294
3460
|
Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
|
|
3295
|
-
Object.defineProperty(
|
|
3461
|
+
Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
|
|
3296
3462
|
})(rpc[i]);
|
|
3297
3463
|
}
|
|
3298
3464
|
|
|
@@ -3310,14 +3476,15 @@
|
|
|
3310
3476
|
/**
|
|
3311
3477
|
* Abstract service method.
|
|
3312
3478
|
* @exports ProtoBuf.Reflect.Service.Method
|
|
3479
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3313
3480
|
* @param {!ProtoBuf.Reflect.Service} svc Service
|
|
3314
3481
|
* @param {string} name Method name
|
|
3315
3482
|
* @param {Object.<string,*>=} options Options
|
|
3316
3483
|
* @constructor
|
|
3317
3484
|
* @extends ProtoBuf.Reflect.T
|
|
3318
3485
|
*/
|
|
3319
|
-
var Method = function(svc, name, options) {
|
|
3320
|
-
T.call(this, svc, name);
|
|
3486
|
+
var Method = function(builder, svc, name, options) {
|
|
3487
|
+
T.call(this, builder, svc, name);
|
|
3321
3488
|
|
|
3322
3489
|
/**
|
|
3323
3490
|
* @override
|
|
@@ -3332,8 +3499,11 @@
|
|
|
3332
3499
|
this.options = options || {};
|
|
3333
3500
|
};
|
|
3334
3501
|
|
|
3335
|
-
|
|
3336
|
-
|
|
3502
|
+
/**
|
|
3503
|
+
* @alias ProtoBuf.Reflect.Service.Method.prototype
|
|
3504
|
+
* @inner
|
|
3505
|
+
*/
|
|
3506
|
+
var MethodPrototype = Method.prototype = Object.create(T.prototype);
|
|
3337
3507
|
|
|
3338
3508
|
/**
|
|
3339
3509
|
* Builds the method's '$options' property.
|
|
@@ -3341,7 +3511,7 @@
|
|
|
3341
3511
|
* @function
|
|
3342
3512
|
* @return {Object.<string,*>}
|
|
3343
3513
|
*/
|
|
3344
|
-
|
|
3514
|
+
MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
|
|
3345
3515
|
|
|
3346
3516
|
/**
|
|
3347
3517
|
* @alias ProtoBuf.Reflect.Service.Method
|
|
@@ -3352,6 +3522,7 @@
|
|
|
3352
3522
|
/**
|
|
3353
3523
|
* RPC service method.
|
|
3354
3524
|
* @exports ProtoBuf.Reflect.Service.RPCMethod
|
|
3525
|
+
* @param {!ProtoBuf.Builder} builder Builder reference
|
|
3355
3526
|
* @param {!ProtoBuf.Reflect.Service} svc Service
|
|
3356
3527
|
* @param {string} name Method name
|
|
3357
3528
|
* @param {string} request Request message name
|
|
@@ -3360,8 +3531,8 @@
|
|
|
3360
3531
|
* @constructor
|
|
3361
3532
|
* @extends ProtoBuf.Reflect.Service.Method
|
|
3362
3533
|
*/
|
|
3363
|
-
var RPCMethod = function(svc, name, request, response, options) {
|
|
3364
|
-
Method.call(this, svc, name, options);
|
|
3534
|
+
var RPCMethod = function(builder, svc, name, request, response, options) {
|
|
3535
|
+
Method.call(this, builder, svc, name, options);
|
|
3365
3536
|
|
|
3366
3537
|
/**
|
|
3367
3538
|
* @override
|
|
@@ -3407,6 +3578,7 @@
|
|
|
3407
3578
|
Reflect.Service.RPCMethod = RPCMethod;
|
|
3408
3579
|
|
|
3409
3580
|
return Reflect;
|
|
3581
|
+
|
|
3410
3582
|
})(ProtoBuf);
|
|
3411
3583
|
|
|
3412
3584
|
/**
|
|
@@ -3420,16 +3592,17 @@
|
|
|
3420
3592
|
* Constructs a new Builder.
|
|
3421
3593
|
* @exports ProtoBuf.Builder
|
|
3422
3594
|
* @class Provides the functionality to build protocol messages.
|
|
3595
|
+
* @param {Object.<string,*>=} options Options
|
|
3423
3596
|
* @constructor
|
|
3424
3597
|
*/
|
|
3425
|
-
var Builder = function() {
|
|
3598
|
+
var Builder = function(options) {
|
|
3426
3599
|
|
|
3427
3600
|
/**
|
|
3428
3601
|
* Namespace.
|
|
3429
3602
|
* @type {ProtoBuf.Reflect.Namespace}
|
|
3430
3603
|
* @expose
|
|
3431
3604
|
*/
|
|
3432
|
-
this.ns = new Reflect.Namespace(null, ""); // Global namespace
|
|
3605
|
+
this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
|
|
3433
3606
|
|
|
3434
3607
|
/**
|
|
3435
3608
|
* Namespace pointer.
|
|
@@ -3465,13 +3638,26 @@
|
|
|
3465
3638
|
* @expose
|
|
3466
3639
|
*/
|
|
3467
3640
|
this.importRoot = null;
|
|
3641
|
+
|
|
3642
|
+
/**
|
|
3643
|
+
* Options.
|
|
3644
|
+
* @type {!Object.<string, *>}
|
|
3645
|
+
* @expose
|
|
3646
|
+
*/
|
|
3647
|
+
this.options = options || {};
|
|
3468
3648
|
};
|
|
3469
3649
|
|
|
3650
|
+
/**
|
|
3651
|
+
* @alias ProtoBuf.Builder.prototype
|
|
3652
|
+
* @inner
|
|
3653
|
+
*/
|
|
3654
|
+
var BuilderPrototype = Builder.prototype;
|
|
3655
|
+
|
|
3470
3656
|
/**
|
|
3471
3657
|
* Resets the pointer to the root namespace.
|
|
3472
3658
|
* @expose
|
|
3473
3659
|
*/
|
|
3474
|
-
|
|
3660
|
+
BuilderPrototype.reset = function() {
|
|
3475
3661
|
this.ptr = this.ns;
|
|
3476
3662
|
};
|
|
3477
3663
|
|
|
@@ -3483,7 +3669,7 @@
|
|
|
3483
3669
|
* @throws {Error} If the package name is invalid
|
|
3484
3670
|
* @expose
|
|
3485
3671
|
*/
|
|
3486
|
-
|
|
3672
|
+
BuilderPrototype.define = function(pkg, options) {
|
|
3487
3673
|
if (typeof pkg !== 'string' || !Lang.TYPEREF.test(pkg))
|
|
3488
3674
|
throw Error("Illegal package: "+pkg);
|
|
3489
3675
|
var part = pkg.split("."), i;
|
|
@@ -3492,7 +3678,7 @@
|
|
|
3492
3678
|
throw Error("Illegal package: "+part[i]);
|
|
3493
3679
|
for (i=0; i<part.length; i++) {
|
|
3494
3680
|
if (this.ptr.getChild(part[i]) === null) // Keep existing namespace
|
|
3495
|
-
this.ptr.addChild(new Reflect.Namespace(this.ptr, part[i], options));
|
|
3681
|
+
this.ptr.addChild(new Reflect.Namespace(this, this.ptr, part[i], options));
|
|
3496
3682
|
this.ptr = this.ptr.getChild(part[i]);
|
|
3497
3683
|
}
|
|
3498
3684
|
return this;
|
|
@@ -3606,7 +3792,7 @@
|
|
|
3606
3792
|
* @throws {Error} If a message definition is invalid
|
|
3607
3793
|
* @expose
|
|
3608
3794
|
*/
|
|
3609
|
-
|
|
3795
|
+
BuilderPrototype.create = function(defs) {
|
|
3610
3796
|
if (!defs)
|
|
3611
3797
|
return this; // Nothing to create
|
|
3612
3798
|
if (!ProtoBuf.Util.isArray(defs))
|
|
@@ -3615,35 +3801,51 @@
|
|
|
3615
3801
|
return this;
|
|
3616
3802
|
|
|
3617
3803
|
// It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
|
|
3618
|
-
var stack = []
|
|
3804
|
+
var stack = [];
|
|
3619
3805
|
stack.push(defs); // One level [a, b, c]
|
|
3620
3806
|
while (stack.length > 0) {
|
|
3621
3807
|
defs = stack.pop();
|
|
3622
3808
|
if (ProtoBuf.Util.isArray(defs)) { // Stack always contains entire namespaces
|
|
3623
3809
|
while (defs.length > 0) {
|
|
3624
|
-
def = defs.shift(); // Namespace always contains an array of messages, enums and services
|
|
3810
|
+
var def = defs.shift(); // Namespace always contains an array of messages, enums and services
|
|
3625
3811
|
if (Builder.isValidMessage(def)) {
|
|
3626
|
-
obj = new Reflect.Message(this.ptr, def["name"], def["options"], def["isGroup"]);
|
|
3812
|
+
var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"]);
|
|
3813
|
+
// Create OneOfs
|
|
3814
|
+
var oneofs = {};
|
|
3815
|
+
if (def["oneofs"]) {
|
|
3816
|
+
var keys = Object.keys(def["oneofs"]);
|
|
3817
|
+
for (var i=0, k=keys.length; i<k; ++i)
|
|
3818
|
+
obj.addChild(oneofs[keys[i]] = new Reflect.Message.OneOf(this, obj, keys[i]));
|
|
3819
|
+
}
|
|
3627
3820
|
// Create fields
|
|
3628
3821
|
if (def["fields"] && def["fields"].length > 0) {
|
|
3629
|
-
for (i=0
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3822
|
+
for (i=0, k=def["fields"].length; i<k; ++i) { // i:k=Fields
|
|
3823
|
+
var fld = def['fields'][i];
|
|
3824
|
+
if (obj.getChild(fld['id']) !== null)
|
|
3825
|
+
throw Error("Duplicate field id in message "+obj.name+": "+fld['id']);
|
|
3826
|
+
if (fld["options"]) {
|
|
3827
|
+
var opts = Object.keys(fld["options"]);
|
|
3828
|
+
for (var j= 0,l=opts.length; j<l; ++j) { // j:l=Option names
|
|
3829
|
+
if (typeof opts[j] !== 'string')
|
|
3830
|
+
throw Error("Illegal field option name in message "+obj.name+"#"+fld["name"]+": "+opts[j]);
|
|
3831
|
+
if (typeof fld["options"][opts[j]] !== 'string' && typeof fld["options"][opts[j]] !== 'number' && typeof fld["options"][opts[j]] !== 'boolean')
|
|
3832
|
+
throw Error("Illegal field option value in message "+obj.name+"#"+fld["name"]+"#"+opts[j]+": "+fld["options"][opts[j]]);
|
|
3639
3833
|
}
|
|
3640
|
-
subObj = null;
|
|
3641
3834
|
}
|
|
3642
|
-
|
|
3835
|
+
var oneof = null;
|
|
3836
|
+
if (typeof fld["oneof"] === 'string') {
|
|
3837
|
+
oneof = oneofs[fld["oneof"]];
|
|
3838
|
+
if (typeof oneof === 'undefined')
|
|
3839
|
+
throw Error("Illegal oneof in message "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
|
|
3840
|
+
}
|
|
3841
|
+
fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["type"], fld["name"], fld["id"], fld["options"], oneof);
|
|
3842
|
+
if (oneof)
|
|
3843
|
+
oneof.fields.push(fld);
|
|
3844
|
+
obj.addChild(fld);
|
|
3643
3845
|
}
|
|
3644
3846
|
}
|
|
3645
3847
|
// Push enums and messages to stack
|
|
3646
|
-
subObj = [];
|
|
3848
|
+
var subObj = [];
|
|
3647
3849
|
if (typeof def["enums"] !== 'undefined' && def['enums'].length > 0)
|
|
3648
3850
|
for (i=0; i<def["enums"].length; i++)
|
|
3649
3851
|
subObj.push(def["enums"][i]);
|
|
@@ -3670,16 +3872,16 @@
|
|
|
3670
3872
|
subObj = null;
|
|
3671
3873
|
obj = null;
|
|
3672
3874
|
} else if (Builder.isValidEnum(def)) {
|
|
3673
|
-
obj = new Reflect.Enum(this.ptr, def["name"], def["options"]);
|
|
3875
|
+
obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"]);
|
|
3674
3876
|
for (i=0; i<def["values"].length; i++)
|
|
3675
|
-
obj.addChild(new Reflect.Enum.Value(obj, def["values"][i]["name"], def["values"][i]["id"]));
|
|
3877
|
+
obj.addChild(new Reflect.Enum.Value(this, obj, def["values"][i]["name"], def["values"][i]["id"]));
|
|
3676
3878
|
this.ptr.addChild(obj);
|
|
3677
3879
|
obj = null;
|
|
3678
3880
|
} else if (Builder.isValidService(def)) {
|
|
3679
|
-
obj = new Reflect.Service(this.ptr, def["name"], def["options"]);
|
|
3881
|
+
obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
|
|
3680
3882
|
for (i in def["rpc"])
|
|
3681
3883
|
if (def["rpc"].hasOwnProperty(i))
|
|
3682
|
-
obj.addChild(new Reflect.Service.RPCMethod(obj, i, def["rpc"][i]["request"], def["rpc"][i]["response"], def["rpc"][i]["options"]));
|
|
3884
|
+
obj.addChild(new Reflect.Service.RPCMethod(this, obj, i, def["rpc"][i]["request"], def["rpc"][i]["response"], def["rpc"][i]["options"]));
|
|
3683
3885
|
this.ptr.addChild(obj);
|
|
3684
3886
|
obj = null;
|
|
3685
3887
|
} else if (Builder.isValidExtend(def)) {
|
|
@@ -3690,10 +3892,16 @@
|
|
|
3690
3892
|
throw Error("Duplicate extended field id in message "+obj.name+": "+def['fields'][i]['id']);
|
|
3691
3893
|
if (def['fields'][i]['id'] < obj.extensions[0] || def['fields'][i]['id'] > obj.extensions[1])
|
|
3692
3894
|
throw Error("Illegal extended field id in message "+obj.name+": "+def['fields'][i]['id']+" ("+obj.extensions.join(' to ')+" expected)");
|
|
3895
|
+
// Convert extension field names to camel case notation if the override is set
|
|
3896
|
+
var name = def["fields"][i]["name"];
|
|
3897
|
+
if (this.options['convertFieldsToCamelCase'])
|
|
3898
|
+
name = Reflect.Message.Field._toCamelCase(def["fields"][i]["name"]);
|
|
3693
3899
|
// see #161: Extensions use their fully qualified name as their runtime key and...
|
|
3694
|
-
|
|
3695
|
-
// ...are added on top of the current namespace as an extension which is used for
|
|
3696
|
-
|
|
3900
|
+
fld = new Reflect.Message.ExtensionField(this, obj, def["fields"][i]["rule"], def["fields"][i]["type"], this.ptr.fqn()+'.'+name, def["fields"][i]["id"], def["fields"][i]["options"]);
|
|
3901
|
+
// ...are added on top of the current namespace as an extension which is used for
|
|
3902
|
+
// resolving their type later on (the extension always keeps the original name to
|
|
3903
|
+
// prevent naming collisions)
|
|
3904
|
+
var ext = new Reflect.Extension(this, this.ptr, def["fields"][i]["name"], fld);
|
|
3697
3905
|
fld.extension = ext;
|
|
3698
3906
|
this.ptr.addChild(ext);
|
|
3699
3907
|
obj.addChild(fld);
|
|
@@ -3723,7 +3931,7 @@
|
|
|
3723
3931
|
* @throws {Error} If the definition or file cannot be imported
|
|
3724
3932
|
* @expose
|
|
3725
3933
|
*/
|
|
3726
|
-
|
|
3934
|
+
BuilderPrototype["import"] = function(json, filename) {
|
|
3727
3935
|
if (typeof filename === 'string') {
|
|
3728
3936
|
if (ProtoBuf.Util.IS_NODE)
|
|
3729
3937
|
filename = require("path")['resolve'](filename);
|
|
@@ -3857,7 +4065,7 @@
|
|
|
3857
4065
|
* @throws {Error} If a type cannot be resolved
|
|
3858
4066
|
* @expose
|
|
3859
4067
|
*/
|
|
3860
|
-
|
|
4068
|
+
BuilderPrototype.resolveAll = function() {
|
|
3861
4069
|
// Resolve all reflected objects
|
|
3862
4070
|
var res;
|
|
3863
4071
|
if (this.ptr == null || typeof this.ptr.type === 'object')
|
|
@@ -3900,9 +4108,7 @@
|
|
|
3900
4108
|
// Should not happen as nothing else is implemented
|
|
3901
4109
|
throw Error("Illegal service type in "+this.ptr.toString(true));
|
|
3902
4110
|
}
|
|
3903
|
-
} else if (this.ptr instanceof ProtoBuf.Reflect.Extension)
|
|
3904
|
-
// There are no runtime counterparts to extensions
|
|
3905
|
-
} else
|
|
4111
|
+
} else if (!(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && !(this.ptr instanceof ProtoBuf.Reflect.Extension))
|
|
3906
4112
|
throw Error("Illegal object in namespace: "+typeof(this.ptr)+":"+this.ptr);
|
|
3907
4113
|
this.reset();
|
|
3908
4114
|
};
|
|
@@ -3915,7 +4121,7 @@
|
|
|
3915
4121
|
* @throws {Error} If a type could not be resolved
|
|
3916
4122
|
* @expose
|
|
3917
4123
|
*/
|
|
3918
|
-
|
|
4124
|
+
BuilderPrototype.build = function(path) {
|
|
3919
4125
|
this.reset();
|
|
3920
4126
|
if (!this.resolved)
|
|
3921
4127
|
this.resolveAll(),
|
|
@@ -3944,7 +4150,7 @@
|
|
|
3944
4150
|
* @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
|
|
3945
4151
|
* @return {ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
|
|
3946
4152
|
*/
|
|
3947
|
-
|
|
4153
|
+
BuilderPrototype.lookup = function(path) {
|
|
3948
4154
|
return path ? this.ns.resolve(path) : this.ns;
|
|
3949
4155
|
};
|
|
3950
4156
|
|
|
@@ -3953,7 +4159,7 @@
|
|
|
3953
4159
|
* @return {string} String representation as of "Builder"
|
|
3954
4160
|
* @expose
|
|
3955
4161
|
*/
|
|
3956
|
-
|
|
4162
|
+
BuilderPrototype.toString = function() {
|
|
3957
4163
|
return "Builder";
|
|
3958
4164
|
};
|
|
3959
4165
|
|
|
@@ -3977,10 +4183,9 @@
|
|
|
3977
4183
|
* @expose
|
|
3978
4184
|
*/
|
|
3979
4185
|
ProtoBuf.loadProto = function(proto, builder, filename) {
|
|
3980
|
-
if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))
|
|
3981
|
-
filename = builder
|
|
3982
|
-
builder =
|
|
3983
|
-
}
|
|
4186
|
+
if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))
|
|
4187
|
+
filename = builder,
|
|
4188
|
+
builder = undefined;
|
|
3984
4189
|
return ProtoBuf.loadJson((new ProtoBuf.DotProto.Parser(proto)).parse(), builder, filename);
|
|
3985
4190
|
};
|
|
3986
4191
|
|
|
@@ -4047,18 +4252,18 @@
|
|
|
4047
4252
|
|
|
4048
4253
|
|
|
4049
4254
|
/**
|
|
4050
|
-
* Constructs a new Builder
|
|
4051
|
-
* @param {string
|
|
4052
|
-
*
|
|
4053
|
-
* @param {Object.<string,*>=} options Top level options
|
|
4054
|
-
* @return {ProtoBuf.Builder} New Builder
|
|
4255
|
+
* Constructs a new empty Builder.
|
|
4256
|
+
* @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf
|
|
4257
|
+
* @return {!ProtoBuf.Builder} Builder
|
|
4055
4258
|
* @expose
|
|
4056
4259
|
*/
|
|
4057
|
-
ProtoBuf.newBuilder = function(
|
|
4058
|
-
|
|
4059
|
-
if (typeof
|
|
4060
|
-
|
|
4061
|
-
|
|
4260
|
+
ProtoBuf.newBuilder = function(options) {
|
|
4261
|
+
options = options || {};
|
|
4262
|
+
if (typeof options['convertFieldsToCamelCase'] === 'undefined')
|
|
4263
|
+
options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
|
|
4264
|
+
if (typeof options['populateAccessors'] === 'undefined')
|
|
4265
|
+
options['populateAccessors'] = ProtoBuf.populateAccessors;
|
|
4266
|
+
return new ProtoBuf.Builder(options);
|
|
4062
4267
|
};
|
|
4063
4268
|
|
|
4064
4269
|
/**
|
|
@@ -4080,7 +4285,6 @@
|
|
|
4080
4285
|
json = JSON.parse(json);
|
|
4081
4286
|
builder["import"](json, filename);
|
|
4082
4287
|
builder.resolveAll();
|
|
4083
|
-
builder.build();
|
|
4084
4288
|
return builder;
|
|
4085
4289
|
};
|
|
4086
4290
|
|
|
@@ -4121,8 +4325,8 @@
|
|
|
4121
4325
|
return ProtoBuf;
|
|
4122
4326
|
}
|
|
4123
4327
|
|
|
4124
|
-
/* CommonJS */ if (typeof module
|
|
4125
|
-
module[
|
|
4328
|
+
/* CommonJS */ if (typeof require === 'function' && typeof module === 'object' && module && typeof exports === 'object' && exports)
|
|
4329
|
+
module['exports'] = init(require("bytebuffer"));
|
|
4126
4330
|
/* AMD */ else if (typeof define === 'function' && define["amd"])
|
|
4127
4331
|
define(["ByteBuffer"], init);
|
|
4128
4332
|
/* Global */ else
|