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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* Constructs a new Parser.
|
|
8
8
|
* @exports ProtoBuf.DotProto.Parser
|
|
9
|
-
* @class
|
|
9
|
+
* @class prototype parser
|
|
10
10
|
* @param {string} proto Protocol source
|
|
11
11
|
* @constructor
|
|
12
12
|
*/
|
|
@@ -20,13 +20,19 @@ var Parser = function(proto) {
|
|
|
20
20
|
this.tn = new Tokenizer(proto);
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @alias ProtoBuf.DotProto.Parser.prototype
|
|
25
|
+
* @inner
|
|
26
|
+
*/
|
|
27
|
+
var ParserPrototype = Parser.prototype;
|
|
28
|
+
|
|
23
29
|
/**
|
|
24
30
|
* Runs the parser.
|
|
25
31
|
* @return {{package: string|null, messages: Array.<object>, enums: Array.<object>, imports: Array.<string>, options: object<string,*>}}
|
|
26
32
|
* @throws {Error} If the source cannot be parsed
|
|
27
33
|
* @expose
|
|
28
34
|
*/
|
|
29
|
-
|
|
35
|
+
ParserPrototype.parse = function() {
|
|
30
36
|
var topLevel = {
|
|
31
37
|
"name": "[ROOT]", // temporary
|
|
32
38
|
"package": null,
|
|
@@ -41,12 +47,12 @@ Parser.prototype.parse = function() {
|
|
|
41
47
|
switch (token) {
|
|
42
48
|
case 'package':
|
|
43
49
|
if (!head || topLevel["package"] !== null)
|
|
44
|
-
throw Error("
|
|
50
|
+
throw Error("Unexpected package at line "+this.tn.line);
|
|
45
51
|
topLevel["package"] = this._parsePackage(token);
|
|
46
52
|
break;
|
|
47
53
|
case 'import':
|
|
48
54
|
if (!head)
|
|
49
|
-
throw Error("
|
|
55
|
+
throw Error("Unexpected import at line "+this.tn.line);
|
|
50
56
|
topLevel.imports.push(this._parseImport(token));
|
|
51
57
|
break;
|
|
52
58
|
case 'message':
|
|
@@ -59,7 +65,7 @@ Parser.prototype.parse = function() {
|
|
|
59
65
|
break;
|
|
60
66
|
case 'option':
|
|
61
67
|
if (!head)
|
|
62
|
-
throw Error("
|
|
68
|
+
throw Error("Unexpected option at line "+this.tn.line);
|
|
63
69
|
this._parseOption(topLevel, token);
|
|
64
70
|
break;
|
|
65
71
|
case 'service':
|
|
@@ -72,7 +78,7 @@ Parser.prototype.parse = function() {
|
|
|
72
78
|
this._parseIgnoredStatement(topLevel, token);
|
|
73
79
|
break;
|
|
74
80
|
default:
|
|
75
|
-
throw Error("
|
|
81
|
+
throw Error("Unexpected token at line "+this.tn.line+": "+token);
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
delete topLevel["name"];
|
|
@@ -86,7 +92,7 @@ Parser.prototype.parse = function() {
|
|
|
86
92
|
* @throws {Error} If the number value is invalid
|
|
87
93
|
* @private
|
|
88
94
|
*/
|
|
89
|
-
|
|
95
|
+
ParserPrototype._parseNumber = function(val) {
|
|
90
96
|
var sign = 1;
|
|
91
97
|
if (val.charAt(0) == '-')
|
|
92
98
|
sign = -1,
|
|
@@ -104,18 +110,17 @@ Parser.prototype._parseNumber = function(val) {
|
|
|
104
110
|
|
|
105
111
|
/**
|
|
106
112
|
* Parses a (possibly multiline) string.
|
|
107
|
-
* @param {string} context Context description
|
|
108
113
|
* @returns {string}
|
|
109
114
|
* @private
|
|
110
115
|
*/
|
|
111
|
-
|
|
116
|
+
ParserPrototype._parseString = function() {
|
|
112
117
|
var value = "", token;
|
|
113
118
|
do {
|
|
114
119
|
token = this.tn.next(); // Known to be = this.tn.stringEndsWith
|
|
115
120
|
value += this.tn.next();
|
|
116
121
|
token = this.tn.next();
|
|
117
122
|
if (token !== this.tn.stringEndsWith)
|
|
118
|
-
throw Error("Illegal end of string
|
|
123
|
+
throw Error("Illegal end of string at line "+this.tn.line+": "+token);
|
|
119
124
|
token = this.tn.peek();
|
|
120
125
|
} while (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ);
|
|
121
126
|
return value;
|
|
@@ -129,7 +134,7 @@ Parser.prototype._parseString = function(context) {
|
|
|
129
134
|
* @throws {Error} If the ID value is invalid
|
|
130
135
|
* @private
|
|
131
136
|
*/
|
|
132
|
-
|
|
137
|
+
ParserPrototype._parseId = function(val, neg) {
|
|
133
138
|
var id = -1;
|
|
134
139
|
var sign = 1;
|
|
135
140
|
if (val.charAt(0) == '-')
|
|
@@ -142,10 +147,10 @@ Parser.prototype._parseId = function(val, neg) {
|
|
|
142
147
|
else if (Lang.NUMBER_OCT.test(val))
|
|
143
148
|
id = parseInt(val.substring(1), 8);
|
|
144
149
|
else
|
|
145
|
-
throw Error("Illegal
|
|
150
|
+
throw Error("Illegal id at line "+this.tn.line+": "+(sign < 0 ? '-' : '')+val);
|
|
146
151
|
id = (sign*id)|0; // Force to 32bit
|
|
147
152
|
if (!neg && id < 0)
|
|
148
|
-
throw Error("Illegal
|
|
153
|
+
throw Error("Illegal id at line "+this.tn.line+": "+(sign < 0 ? '-' : '')+val);
|
|
149
154
|
return id;
|
|
150
155
|
};
|
|
151
156
|
|
|
@@ -156,14 +161,14 @@ Parser.prototype._parseId = function(val, neg) {
|
|
|
156
161
|
* @throws {Error} If the package definition cannot be parsed
|
|
157
162
|
* @private
|
|
158
163
|
*/
|
|
159
|
-
|
|
164
|
+
ParserPrototype._parsePackage = function(token) {
|
|
160
165
|
token = this.tn.next();
|
|
161
166
|
if (!Lang.TYPEREF.test(token))
|
|
162
|
-
throw Error("Illegal package at line "+this.tn.line+": "+token);
|
|
167
|
+
throw Error("Illegal package name at line "+this.tn.line+": "+token);
|
|
163
168
|
var pkg = token;
|
|
164
169
|
token = this.tn.next();
|
|
165
170
|
if (token != Lang.END)
|
|
166
|
-
throw Error("Illegal end of package at line "+this.tn.line+": "+token
|
|
171
|
+
throw Error("Illegal end of package at line "+this.tn.line+": "+token);
|
|
167
172
|
return pkg;
|
|
168
173
|
};
|
|
169
174
|
|
|
@@ -174,17 +179,17 @@ Parser.prototype._parsePackage = function(token) {
|
|
|
174
179
|
* @throws {Error} If the import definition cannot be parsed
|
|
175
180
|
* @private
|
|
176
181
|
*/
|
|
177
|
-
|
|
182
|
+
ParserPrototype._parseImport = function(token) {
|
|
178
183
|
token = this.tn.peek();
|
|
179
184
|
if (token === "public")
|
|
180
185
|
this.tn.next(),
|
|
181
186
|
token = this.tn.peek();
|
|
182
187
|
if (token !== Lang.STRINGOPEN && token !== Lang.STRINGOPEN_SQ)
|
|
183
|
-
throw Error("Illegal import at line "+this.tn.line+": "+token
|
|
184
|
-
var imported = this._parseString(
|
|
188
|
+
throw Error("Illegal start of import at line "+this.tn.line+": "+token);
|
|
189
|
+
var imported = this._parseString();
|
|
185
190
|
token = this.tn.next();
|
|
186
191
|
if (token !== Lang.END)
|
|
187
|
-
throw Error("Illegal import at line "+this.tn.line+": "+token
|
|
192
|
+
throw Error("Illegal end of import at line "+this.tn.line+": "+token);
|
|
188
193
|
return imported;
|
|
189
194
|
};
|
|
190
195
|
|
|
@@ -195,7 +200,7 @@ Parser.prototype._parseImport = function(token) {
|
|
|
195
200
|
* @throws {Error} If the option cannot be parsed
|
|
196
201
|
* @private
|
|
197
202
|
*/
|
|
198
|
-
|
|
203
|
+
ParserPrototype._parseOption = function(parent, token) {
|
|
199
204
|
token = this.tn.next();
|
|
200
205
|
var custom = false;
|
|
201
206
|
if (token == Lang.COPTOPEN)
|
|
@@ -204,12 +209,12 @@ Parser.prototype._parseOption = function(parent, token) {
|
|
|
204
209
|
if (!Lang.TYPEREF.test(token))
|
|
205
210
|
// we can allow options of the form google.protobuf.* since they will just get ignored anyways
|
|
206
211
|
if (!/google\.protobuf\./.test(token))
|
|
207
|
-
throw Error("Illegal option in message "+parent.name+" at line "+this.tn.line+": "+token);
|
|
212
|
+
throw Error("Illegal option name in message "+parent.name+" at line "+this.tn.line+": "+token);
|
|
208
213
|
var name = token;
|
|
209
214
|
token = this.tn.next();
|
|
210
215
|
if (custom) { // (my_method_option).foo, (my_method_option), some_method_option, (foo.my_option).bar
|
|
211
216
|
if (token !== Lang.COPTCLOSE)
|
|
212
|
-
throw Error("Illegal
|
|
217
|
+
throw Error("Illegal end in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
213
218
|
name = '('+name+')';
|
|
214
219
|
token = this.tn.next();
|
|
215
220
|
if (Lang.FQTYPEREF.test(token))
|
|
@@ -217,11 +222,11 @@ Parser.prototype._parseOption = function(parent, token) {
|
|
|
217
222
|
token = this.tn.next();
|
|
218
223
|
}
|
|
219
224
|
if (token !== Lang.EQUAL)
|
|
220
|
-
throw Error("Illegal
|
|
225
|
+
throw Error("Illegal operator in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
221
226
|
var value;
|
|
222
227
|
token = this.tn.peek();
|
|
223
228
|
if (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ)
|
|
224
|
-
value = this._parseString(
|
|
229
|
+
value = this._parseString();
|
|
225
230
|
else {
|
|
226
231
|
this.tn.next();
|
|
227
232
|
if (Lang.NUMBER.test(token))
|
|
@@ -235,7 +240,7 @@ Parser.prototype._parseOption = function(parent, token) {
|
|
|
235
240
|
}
|
|
236
241
|
token = this.tn.next();
|
|
237
242
|
if (token !== Lang.END)
|
|
238
|
-
throw Error("Illegal end of option in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token
|
|
243
|
+
throw Error("Illegal end of option in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
239
244
|
parent["options"][name] = value;
|
|
240
245
|
};
|
|
241
246
|
|
|
@@ -246,12 +251,12 @@ Parser.prototype._parseOption = function(parent, token) {
|
|
|
246
251
|
* @throws {Error} If the directive cannot be parsed
|
|
247
252
|
* @private
|
|
248
253
|
*/
|
|
249
|
-
|
|
254
|
+
ParserPrototype._parseIgnoredStatement = function(parent, keyword) {
|
|
250
255
|
var token;
|
|
251
256
|
do {
|
|
252
257
|
token = this.tn.next();
|
|
253
258
|
if (token === null)
|
|
254
|
-
throw Error("Unexpected EOF in "+parent.name+", "+keyword+"
|
|
259
|
+
throw Error("Unexpected EOF in "+parent.name+", "+keyword+" at line "+this.tn.line);
|
|
255
260
|
if (token === Lang.END)
|
|
256
261
|
break;
|
|
257
262
|
} while (true);
|
|
@@ -264,7 +269,7 @@ Parser.prototype._parseIgnoredStatement = function(parent, keyword) {
|
|
|
264
269
|
* @throws {Error} If the service cannot be parsed
|
|
265
270
|
* @private
|
|
266
271
|
*/
|
|
267
|
-
|
|
272
|
+
ParserPrototype._parseService = function(parent, token) {
|
|
268
273
|
token = this.tn.next();
|
|
269
274
|
if (!Lang.NAME.test(token))
|
|
270
275
|
throw Error("Illegal service name at line "+this.tn.line+": "+token);
|
|
@@ -276,7 +281,7 @@ Parser.prototype._parseService = function(parent, token) {
|
|
|
276
281
|
};
|
|
277
282
|
token = this.tn.next();
|
|
278
283
|
if (token !== Lang.OPEN)
|
|
279
|
-
throw Error("Illegal
|
|
284
|
+
throw Error("Illegal start of service "+name+" at line "+this.tn.line+": "+token);
|
|
280
285
|
do {
|
|
281
286
|
token = this.tn.next();
|
|
282
287
|
if (token === "option")
|
|
@@ -284,7 +289,7 @@ Parser.prototype._parseService = function(parent, token) {
|
|
|
284
289
|
else if (token === 'rpc')
|
|
285
290
|
this._parseServiceRPC(svc, token);
|
|
286
291
|
else if (token !== Lang.CLOSE)
|
|
287
|
-
throw Error("Illegal type
|
|
292
|
+
throw Error("Illegal type of service "+name+" at line "+this.tn.line+": "+token);
|
|
288
293
|
} while (token !== Lang.CLOSE);
|
|
289
294
|
parent["services"].push(svc);
|
|
290
295
|
};
|
|
@@ -295,11 +300,11 @@ Parser.prototype._parseService = function(parent, token) {
|
|
|
295
300
|
* @param {string} token Initial token
|
|
296
301
|
* @private
|
|
297
302
|
*/
|
|
298
|
-
|
|
303
|
+
ParserPrototype._parseServiceRPC = function(svc, token) {
|
|
299
304
|
var type = token;
|
|
300
305
|
token = this.tn.next();
|
|
301
306
|
if (!Lang.NAME.test(token))
|
|
302
|
-
throw Error("Illegal
|
|
307
|
+
throw Error("Illegal method name in service "+svc["name"]+" at line "+this.tn.line+": "+token);
|
|
303
308
|
var name = token;
|
|
304
309
|
var method = {
|
|
305
310
|
"request": null,
|
|
@@ -308,25 +313,25 @@ Parser.prototype._parseServiceRPC = function(svc, token) {
|
|
|
308
313
|
};
|
|
309
314
|
token = this.tn.next();
|
|
310
315
|
if (token !== Lang.COPTOPEN)
|
|
311
|
-
throw Error("Illegal start of request type in
|
|
316
|
+
throw Error("Illegal start of request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
312
317
|
token = this.tn.next();
|
|
313
318
|
if (!Lang.TYPEREF.test(token))
|
|
314
|
-
throw Error("Illegal request type in
|
|
319
|
+
throw Error("Illegal request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
315
320
|
method["request"] = token;
|
|
316
321
|
token = this.tn.next();
|
|
317
322
|
if (token != Lang.COPTCLOSE)
|
|
318
|
-
throw Error("Illegal end of request type in
|
|
323
|
+
throw Error("Illegal end of request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
319
324
|
token = this.tn.next();
|
|
320
325
|
if (token.toLowerCase() !== "returns")
|
|
321
|
-
throw Error("Illegal
|
|
326
|
+
throw Error("Illegal delimiter in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
322
327
|
token = this.tn.next();
|
|
323
328
|
if (token != Lang.COPTOPEN)
|
|
324
|
-
throw Error("Illegal start of response type in
|
|
329
|
+
throw Error("Illegal start of response type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
325
330
|
token = this.tn.next();
|
|
326
331
|
method["response"] = token;
|
|
327
332
|
token = this.tn.next();
|
|
328
333
|
if (token !== Lang.COPTCLOSE)
|
|
329
|
-
throw Error("Illegal end of response type in
|
|
334
|
+
throw Error("Illegal end of response type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
330
335
|
token = this.tn.next();
|
|
331
336
|
if (token === Lang.OPEN) {
|
|
332
337
|
do {
|
|
@@ -334,12 +339,12 @@ Parser.prototype._parseServiceRPC = function(svc, token) {
|
|
|
334
339
|
if (token === 'option')
|
|
335
340
|
this._parseOption(method, token); // <- will fail for the custom-options example
|
|
336
341
|
else if (token !== Lang.CLOSE)
|
|
337
|
-
throw Error("Illegal start of option
|
|
342
|
+
throw Error("Illegal start of option inservice "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
338
343
|
} while (token !== Lang.CLOSE);
|
|
339
344
|
if (this.tn.peek() === Lang.END)
|
|
340
345
|
this.tn.next();
|
|
341
346
|
} else if (token !== Lang.END)
|
|
342
|
-
throw Error("Illegal
|
|
347
|
+
throw Error("Illegal delimiter in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
|
|
343
348
|
if (typeof svc[type] === 'undefined')
|
|
344
349
|
svc[type] = {};
|
|
345
350
|
svc[type][name] = method;
|
|
@@ -354,7 +359,7 @@ Parser.prototype._parseServiceRPC = function(svc, token) {
|
|
|
354
359
|
* @throws {Error} If the message cannot be parsed
|
|
355
360
|
* @private
|
|
356
361
|
*/
|
|
357
|
-
|
|
362
|
+
ParserPrototype._parseMessage = function(parent, fld, token) {
|
|
358
363
|
/** @dict */
|
|
359
364
|
var msg = {}; // Note: At some point we might want to exclude the parser, so we need a dict.
|
|
360
365
|
var isGroup = token === "group";
|
|
@@ -365,7 +370,7 @@ Parser.prototype._parseMessage = function(parent, fld, token) {
|
|
|
365
370
|
if (isGroup) {
|
|
366
371
|
token = this.tn.next();
|
|
367
372
|
if (token !== Lang.EQUAL)
|
|
368
|
-
throw Error("Illegal id assignment after group "+msg.name+" at line "+this.tn.line+": "+token
|
|
373
|
+
throw Error("Illegal id assignment after group "+msg.name+" at line "+this.tn.line+": "+token);
|
|
369
374
|
token = this.tn.next();
|
|
370
375
|
try {
|
|
371
376
|
fld["id"] = this._parseId(token);
|
|
@@ -378,12 +383,13 @@ Parser.prototype._parseMessage = function(parent, fld, token) {
|
|
|
378
383
|
msg["enums"] = [];
|
|
379
384
|
msg["messages"] = [];
|
|
380
385
|
msg["options"] = {};
|
|
386
|
+
msg["oneofs"] = {};
|
|
381
387
|
token = this.tn.next();
|
|
382
388
|
if (token === Lang.OPTOPEN && fld)
|
|
383
389
|
this._parseFieldOptions(msg, fld, token),
|
|
384
390
|
token = this.tn.next();
|
|
385
391
|
if (token !== Lang.OPEN)
|
|
386
|
-
throw Error("Illegal
|
|
392
|
+
throw Error("Illegal start of "+(isGroup ? "group" : "message")+" "+msg.name+" at line "+this.tn.line+": "+token);
|
|
387
393
|
// msg["extensions"] = undefined
|
|
388
394
|
do {
|
|
389
395
|
token = this.tn.next();
|
|
@@ -394,6 +400,8 @@ Parser.prototype._parseMessage = function(parent, fld, token) {
|
|
|
394
400
|
break;
|
|
395
401
|
} else if (Lang.RULE.test(token))
|
|
396
402
|
this._parseMessageField(msg, token);
|
|
403
|
+
else if (token === "oneof")
|
|
404
|
+
this._parseMessageOneOf(msg, token);
|
|
397
405
|
else if (token === "enum")
|
|
398
406
|
this._parseEnum(msg, token);
|
|
399
407
|
else if (token === "message")
|
|
@@ -405,7 +413,7 @@ Parser.prototype._parseMessage = function(parent, fld, token) {
|
|
|
405
413
|
else if (token === "extend")
|
|
406
414
|
this._parseExtend(msg, token);
|
|
407
415
|
else
|
|
408
|
-
throw Error("Illegal token in message "+msg.name+" at line "+this.tn.line+": "+token
|
|
416
|
+
throw Error("Illegal token in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
409
417
|
} while (true);
|
|
410
418
|
parent["messages"].push(msg);
|
|
411
419
|
return msg;
|
|
@@ -415,10 +423,11 @@ Parser.prototype._parseMessage = function(parent, fld, token) {
|
|
|
415
423
|
* Parses a message field.
|
|
416
424
|
* @param {Object} msg Message definition
|
|
417
425
|
* @param {string} token Initial token
|
|
426
|
+
* @returns {!Object} Field descriptor
|
|
418
427
|
* @throws {Error} If the message field cannot be parsed
|
|
419
428
|
* @private
|
|
420
429
|
*/
|
|
421
|
-
|
|
430
|
+
ParserPrototype._parseMessageField = function(msg, token) {
|
|
422
431
|
/** @dict */
|
|
423
432
|
var fld = {}, grp = null;
|
|
424
433
|
fld["rule"] = token;
|
|
@@ -447,21 +456,48 @@ Parser.prototype._parseMessageField = function(msg, token) {
|
|
|
447
456
|
fld["name"] = token;
|
|
448
457
|
token = this.tn.next();
|
|
449
458
|
if (token !== Lang.EQUAL)
|
|
450
|
-
throw Error("Illegal
|
|
459
|
+
throw Error("Illegal token in field "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
451
460
|
token = this.tn.next();
|
|
452
461
|
try {
|
|
453
462
|
fld["id"] = this._parseId(token);
|
|
454
463
|
} catch (e) {
|
|
455
|
-
throw Error("Illegal field id
|
|
464
|
+
throw Error("Illegal field id in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
456
465
|
}
|
|
457
466
|
token = this.tn.next();
|
|
458
467
|
if (token === Lang.OPTOPEN)
|
|
459
468
|
this._parseFieldOptions(msg, fld, token),
|
|
460
469
|
token = this.tn.next();
|
|
461
470
|
if (token !== Lang.END)
|
|
462
|
-
throw Error("Illegal
|
|
471
|
+
throw Error("Illegal delimiter in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
463
472
|
}
|
|
464
473
|
msg["fields"].push(fld);
|
|
474
|
+
return fld;
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Parses a message oneof.
|
|
479
|
+
* @param {Object} msg Message definition
|
|
480
|
+
* @param {string} token Initial token
|
|
481
|
+
* @throws {Error} If the message oneof cannot be parsed
|
|
482
|
+
* @private
|
|
483
|
+
*/
|
|
484
|
+
ParserPrototype._parseMessageOneOf = function(msg, token) {
|
|
485
|
+
token = this.tn.next();
|
|
486
|
+
if (!Lang.NAME.test(token))
|
|
487
|
+
throw Error("Illegal oneof name in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
488
|
+
var name = token,
|
|
489
|
+
fld;
|
|
490
|
+
var fields = [];
|
|
491
|
+
token = this.tn.next();
|
|
492
|
+
if (token !== Lang.OPEN)
|
|
493
|
+
throw Error("Illegal start of oneof "+name+" at line "+this.tn.line+": "+token);
|
|
494
|
+
while (this.tn.peek() !== Lang.CLOSE) {
|
|
495
|
+
fld = this._parseMessageField(msg, "optional");
|
|
496
|
+
fld["oneof"] = name;
|
|
497
|
+
fields.push(fld["id"]);
|
|
498
|
+
}
|
|
499
|
+
this.tn.next();
|
|
500
|
+
msg["oneofs"][name] = fields;
|
|
465
501
|
};
|
|
466
502
|
|
|
467
503
|
/**
|
|
@@ -472,7 +508,7 @@ Parser.prototype._parseMessageField = function(msg, token) {
|
|
|
472
508
|
* @throws {Error} If the message field options cannot be parsed
|
|
473
509
|
* @private
|
|
474
510
|
*/
|
|
475
|
-
|
|
511
|
+
ParserPrototype._parseFieldOptions = function(msg, fld, token) {
|
|
476
512
|
var first = true;
|
|
477
513
|
do {
|
|
478
514
|
token = this.tn.next();
|
|
@@ -480,7 +516,7 @@ Parser.prototype._parseFieldOptions = function(msg, fld, token) {
|
|
|
480
516
|
break;
|
|
481
517
|
else if (token === Lang.OPTEND) {
|
|
482
518
|
if (first)
|
|
483
|
-
throw Error("Illegal start of
|
|
519
|
+
throw Error("Illegal start of options in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
484
520
|
token = this.tn.next();
|
|
485
521
|
}
|
|
486
522
|
this._parseFieldOption(msg, fld, token);
|
|
@@ -496,18 +532,18 @@ Parser.prototype._parseFieldOptions = function(msg, fld, token) {
|
|
|
496
532
|
* @throws {Error} If the mesage field option cannot be parsed
|
|
497
533
|
* @private
|
|
498
534
|
*/
|
|
499
|
-
|
|
535
|
+
ParserPrototype._parseFieldOption = function(msg, fld, token) {
|
|
500
536
|
var custom = false;
|
|
501
537
|
if (token === Lang.COPTOPEN)
|
|
502
538
|
token = this.tn.next(),
|
|
503
539
|
custom = true;
|
|
504
540
|
if (!Lang.TYPEREF.test(token))
|
|
505
|
-
throw Error("Illegal field option in
|
|
541
|
+
throw Error("Illegal field option in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
506
542
|
var name = token;
|
|
507
543
|
token = this.tn.next();
|
|
508
544
|
if (custom) {
|
|
509
545
|
if (token !== Lang.COPTCLOSE)
|
|
510
|
-
throw Error("Illegal
|
|
546
|
+
throw Error("Illegal delimiter in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
511
547
|
name = '('+name+')';
|
|
512
548
|
token = this.tn.next();
|
|
513
549
|
if (Lang.FQTYPEREF.test(token))
|
|
@@ -515,11 +551,11 @@ Parser.prototype._parseFieldOption = function(msg, fld, token) {
|
|
|
515
551
|
token = this.tn.next();
|
|
516
552
|
}
|
|
517
553
|
if (token !== Lang.EQUAL)
|
|
518
|
-
throw Error("Illegal
|
|
554
|
+
throw Error("Illegal token in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
|
|
519
555
|
var value;
|
|
520
556
|
token = this.tn.peek();
|
|
521
557
|
if (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ) {
|
|
522
|
-
value = this._parseString(
|
|
558
|
+
value = this._parseString();
|
|
523
559
|
} else if (Lang.NUMBER.test(token, true))
|
|
524
560
|
value = this._parseNumber(this.tn.next(), true);
|
|
525
561
|
else if (Lang.BOOL.test(token))
|
|
@@ -527,7 +563,7 @@ Parser.prototype._parseFieldOption = function(msg, fld, token) {
|
|
|
527
563
|
else if (Lang.TYPEREF.test(token))
|
|
528
564
|
value = this.tn.next(); // TODO: Resolve?
|
|
529
565
|
else
|
|
530
|
-
throw Error("Illegal
|
|
566
|
+
throw Error("Illegal value in message "+msg.name+"#"+fld.name+", option "+name+" at line "+this.tn.line+": "+token);
|
|
531
567
|
fld["options"][name] = value;
|
|
532
568
|
};
|
|
533
569
|
|
|
@@ -538,7 +574,7 @@ Parser.prototype._parseFieldOption = function(msg, fld, token) {
|
|
|
538
574
|
* @throws {Error} If the enum cannot be parsed
|
|
539
575
|
* @private
|
|
540
576
|
*/
|
|
541
|
-
|
|
577
|
+
ParserPrototype._parseEnum = function(msg, token) {
|
|
542
578
|
/** @dict */
|
|
543
579
|
var enm = {};
|
|
544
580
|
token = this.tn.next();
|
|
@@ -547,7 +583,7 @@ Parser.prototype._parseEnum = function(msg, token) {
|
|
|
547
583
|
enm["name"] = token;
|
|
548
584
|
token = this.tn.next();
|
|
549
585
|
if (token !== Lang.OPEN)
|
|
550
|
-
throw Error("Illegal
|
|
586
|
+
throw Error("Illegal start of enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
551
587
|
enm["values"] = [];
|
|
552
588
|
enm["options"] = {};
|
|
553
589
|
do {
|
|
@@ -562,7 +598,7 @@ Parser.prototype._parseEnum = function(msg, token) {
|
|
|
562
598
|
this._parseOption(enm, token);
|
|
563
599
|
else {
|
|
564
600
|
if (!Lang.NAME.test(token))
|
|
565
|
-
throw Error("Illegal
|
|
601
|
+
throw Error("Illegal name in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
566
602
|
this._parseEnumValue(enm, token);
|
|
567
603
|
}
|
|
568
604
|
} while (true);
|
|
@@ -576,18 +612,18 @@ Parser.prototype._parseEnum = function(msg, token) {
|
|
|
576
612
|
* @throws {Error} If the enum value cannot be parsed
|
|
577
613
|
* @private
|
|
578
614
|
*/
|
|
579
|
-
|
|
615
|
+
ParserPrototype._parseEnumValue = function(enm, token) {
|
|
580
616
|
/** @dict */
|
|
581
617
|
var val = {};
|
|
582
618
|
val["name"] = token;
|
|
583
619
|
token = this.tn.next();
|
|
584
620
|
if (token !== Lang.EQUAL)
|
|
585
|
-
throw Error("Illegal
|
|
621
|
+
throw Error("Illegal token in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
586
622
|
token = this.tn.next();
|
|
587
623
|
try {
|
|
588
624
|
val["id"] = this._parseId(token, true);
|
|
589
625
|
} catch (e) {
|
|
590
|
-
throw Error("Illegal
|
|
626
|
+
throw Error("Illegal id in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
591
627
|
}
|
|
592
628
|
enm["values"].push(val);
|
|
593
629
|
token = this.tn.next();
|
|
@@ -597,7 +633,7 @@ Parser.prototype._parseEnumValue = function(enm, token) {
|
|
|
597
633
|
token = this.tn.next();
|
|
598
634
|
}
|
|
599
635
|
if (token !== Lang.END)
|
|
600
|
-
throw Error("Illegal
|
|
636
|
+
throw Error("Illegal delimiter in enum "+enm.name+" at line "+this.tn.line+": "+token);
|
|
601
637
|
};
|
|
602
638
|
|
|
603
639
|
/**
|
|
@@ -607,7 +643,7 @@ Parser.prototype._parseEnumValue = function(enm, token) {
|
|
|
607
643
|
* @throws {Error} If the extensions statement cannot be parsed
|
|
608
644
|
* @private
|
|
609
645
|
*/
|
|
610
|
-
|
|
646
|
+
ParserPrototype._parseExtensions = function(msg, token) {
|
|
611
647
|
/** @type {Array.<number>} */
|
|
612
648
|
var range = [];
|
|
613
649
|
token = this.tn.next();
|
|
@@ -619,7 +655,7 @@ Parser.prototype._parseExtensions = function(msg, token) {
|
|
|
619
655
|
range.push(this._parseNumber(token));
|
|
620
656
|
token = this.tn.next();
|
|
621
657
|
if (token !== 'to')
|
|
622
|
-
throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+"
|
|
658
|
+
throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
623
659
|
token = this.tn.next();
|
|
624
660
|
if (token === "min")
|
|
625
661
|
range.push(ProtoBuf.ID_MIN);
|
|
@@ -629,7 +665,7 @@ Parser.prototype._parseExtensions = function(msg, token) {
|
|
|
629
665
|
range.push(this._parseNumber(token));
|
|
630
666
|
token = this.tn.next();
|
|
631
667
|
if (token !== Lang.END)
|
|
632
|
-
throw Error("Illegal
|
|
668
|
+
throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+": "+token);
|
|
633
669
|
return range;
|
|
634
670
|
};
|
|
635
671
|
|
|
@@ -640,17 +676,17 @@ Parser.prototype._parseExtensions = function(msg, token) {
|
|
|
640
676
|
* @throws {Error} If the extend block cannot be parsed
|
|
641
677
|
* @private
|
|
642
678
|
*/
|
|
643
|
-
|
|
679
|
+
ParserPrototype._parseExtend = function(parent, token) {
|
|
644
680
|
token = this.tn.next();
|
|
645
681
|
if (!Lang.TYPEREF.test(token))
|
|
646
|
-
throw Error("Illegal
|
|
682
|
+
throw Error("Illegal message name at line "+this.tn.line+": "+token);
|
|
647
683
|
/** @dict */
|
|
648
684
|
var ext = {};
|
|
649
685
|
ext["ref"] = token;
|
|
650
686
|
ext["fields"] = [];
|
|
651
687
|
token = this.tn.next();
|
|
652
688
|
if (token !== Lang.OPEN)
|
|
653
|
-
throw Error("Illegal
|
|
689
|
+
throw Error("Illegal start of extend "+ext.name+" at line "+this.tn.line+": "+token);
|
|
654
690
|
do {
|
|
655
691
|
token = this.tn.next();
|
|
656
692
|
if (token === Lang.CLOSE) {
|
|
@@ -661,7 +697,7 @@ Parser.prototype._parseExtend = function(parent, token) {
|
|
|
661
697
|
} else if (Lang.RULE.test(token))
|
|
662
698
|
this._parseMessageField(ext, token);
|
|
663
699
|
else
|
|
664
|
-
throw Error("Illegal token in extend "+ext.name+" at line "+this.tn.line+": "+token
|
|
700
|
+
throw Error("Illegal token in extend "+ext.name+" at line "+this.tn.line+": "+token);
|
|
665
701
|
} while (true);
|
|
666
702
|
parent["messages"].push(ext);
|
|
667
703
|
return ext;
|
|
@@ -671,6 +707,6 @@ Parser.prototype._parseExtend = function(parent, token) {
|
|
|
671
707
|
* Returns a string representation of this object.
|
|
672
708
|
* @returns {string} String representation as of "Parser"
|
|
673
709
|
*/
|
|
674
|
-
|
|
710
|
+
ParserPrototype.toString = function() {
|
|
675
711
|
return "Parser";
|
|
676
712
|
};
|