Skip to content

Commit 2a74fbf

Browse files
committed
Other: Everything can be block- or line-style when parsing, see #713
1 parent b01bb58 commit 2a74fbf

File tree

2 files changed

+158
-144
lines changed

2 files changed

+158
-144
lines changed

src/parse.js

Lines changed: 147 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -257,19 +257,24 @@ function parse(source, root, options) {
257257
return false;
258258
}
259259

260-
function ifBlock(obj, fn) {
260+
function ifBlock(obj, fnIf, fnElse) {
261261
var trailingLine = tn.line();
262-
obj.comment = cmnt(); // try block-type comment
263-
obj.filename = parse.filename;
262+
if (obj) {
263+
obj.comment = cmnt(); // try block-type comment
264+
obj.filename = parse.filename;
265+
}
264266
if (skip("{", true)) {
265-
fn();
267+
var token;
268+
while ((token = next()) !== "}")
269+
fnIf(token);
266270
skip(";", true);
267-
return true;
271+
} else {
272+
if (fnElse)
273+
fnElse();
274+
skip(";");
275+
if (obj && typeof obj.comment !== "string")
276+
obj.comment = cmnt(trailingLine); // try line-type comment if no block
268277
}
269-
skip(";");
270-
if (typeof obj.comment !== 'string')
271-
obj.comment = cmnt(trailingLine); // try line-type comment if no block
272-
return false;
273278
}
274279

275280
function parseType(parent, token) {
@@ -279,44 +284,41 @@ function parse(source, root, options) {
279284
throw illegal(token, "type name");
280285

281286
var type = new Type(token);
282-
ifBlock(type, function() {
283-
while ((token = next()) !== "}") {
287+
ifBlock(type, function parseType_block(token) {
288+
if (parseCommon(type, token))
289+
return;
284290

285-
if (parseCommon(type, token))
286-
continue;
291+
switch (token) {
287292

288-
switch (token) {
289-
290-
case "map":
291-
parseMapField(type, token);
292-
break;
293-
294-
case "required":
295-
case "optional":
296-
case "repeated":
297-
parseField(type, token);
298-
break;
299-
300-
case "oneof":
301-
parseOneOf(type, token);
302-
break;
303-
304-
case "extensions":
305-
readRanges(type.extensions || (type.extensions = []));
306-
break;
307-
308-
case "reserved":
309-
readRanges(type.reserved || (type.reserved = []), true);
310-
break;
311-
312-
default:
313-
/* istanbul ignore next */
314-
if (!isProto3 || !typeRefRe.test(token))
315-
throw illegal(token);
316-
push(token);
317-
parseField(type, "optional");
318-
break;
319-
}
293+
case "map":
294+
parseMapField(type, token);
295+
break;
296+
297+
case "required":
298+
case "optional":
299+
case "repeated":
300+
parseField(type, token);
301+
break;
302+
303+
case "oneof":
304+
parseOneOf(type, token);
305+
break;
306+
307+
case "extensions":
308+
readRanges(type.extensions || (type.extensions = []));
309+
break;
310+
311+
case "reserved":
312+
readRanges(type.reserved || (type.reserved = []), true);
313+
break;
314+
315+
default:
316+
/* istanbul ignore next */
317+
if (!isProto3 || !typeRefRe.test(token))
318+
throw illegal(token);
319+
push(token);
320+
parseField(type, "optional");
321+
break;
320322
}
321323
});
322324
parent.add(type);
@@ -341,13 +343,20 @@ function parse(source, root, options) {
341343

342344
name = applyCase(name);
343345
skip("=");
346+
344347
var field = new Field(name, parseId(next()), type, rule, extend),
345-
trailingLine = tn.line();
346-
field.comment = cmnt(); // try block-type
347-
field.filename = parse.filename;
348-
parseInlineOptions(field);
349-
if (!field.comment)
350-
field.comment = cmnt(trailingLine); // try line-type
348+
token;
349+
ifBlock(field, function parseField_block(token) {
350+
/* istanbul ignore else */
351+
if (token === "option") {
352+
parseOption(field, token);
353+
skip(";");
354+
} else
355+
throw illegal(token);
356+
}, function parseField_line() {
357+
parseInlineOptions(field);
358+
});
359+
351360
// JSON defaults to packed=true if not set so we have to set packed=false explicity when
352361
// parsing proto2 descriptors without the option, where applicable. This must be done for
353362
// any type (not just packable types) because enums also use varint encoding and it is not
@@ -373,25 +382,23 @@ function parse(source, root, options) {
373382
type.group = true;
374383
var field = new Field(fieldName, id, name, rule);
375384
field.filename = parse.filename;
376-
ifBlock(type, function() {
377-
while ((token = next()) !== "}") {
378-
switch (token) {
385+
ifBlock(type, function parseGroup_block(token) {
386+
switch (token) {
379387

380-
case "option":
381-
parseOption(type, token);
382-
skip(";");
383-
break;
388+
case "option":
389+
parseOption(type, token);
390+
skip(";");
391+
break;
384392

385-
case "required":
386-
case "optional":
387-
case "repeated":
388-
parseField(type, token);
389-
break;
393+
case "required":
394+
case "optional":
395+
case "repeated":
396+
parseField(type, token);
397+
break;
390398

391-
/* istanbul ignore next */
392-
default:
393-
throw illegal(token); // there are no groups with proto3 semantics
394-
}
399+
/* istanbul ignore next */
400+
default:
401+
throw illegal(token); // there are no groups with proto3 semantics
395402
}
396403
});
397404
parent.add(type)
@@ -418,13 +425,18 @@ function parse(source, root, options) {
418425

419426
name = applyCase(name);
420427
skip("=");
421-
var field = new MapField(name, parseId(next()), keyType, valueType),
422-
trailingLine = tn.line();
423-
field.comment = cmnt(); // try block-type
424-
field.filename = parse.filename;
425-
parseInlineOptions(field);
426-
if (!field.comment)
427-
field.comment = cmnt(trailingLine); // try line-type
428+
var field = new MapField(name, parseId(next()), keyType, valueType);
429+
ifBlock(field, function parseMapField_block(token) {
430+
/* istanbul ignore else */
431+
if (token === "option") {
432+
parseOption(field, token);
433+
skip(";");
434+
} else
435+
throw illegal(token);
436+
}, function parseMapField_line() {
437+
parseInlineOptions(field);
438+
});
439+
428440
parent.add(field);
429441
}
430442

@@ -437,15 +449,13 @@ function parse(source, root, options) {
437449

438450
name = applyCase(name);
439451
var oneof = new OneOf(name);
440-
ifBlock(oneof, function() {
441-
while ((token = next()) !== "}") {
442-
if (token === "option") {
443-
parseOption(oneof, token);
444-
skip(";");
445-
} else {
446-
push(token);
447-
parseField(oneof, "optional");
448-
}
452+
ifBlock(oneof, function parseOneOf_block(token) {
453+
if (token === "option") {
454+
parseOption(oneof, token);
455+
skip(";");
456+
} else {
457+
push(token);
458+
parseField(oneof, "optional");
449459
}
450460
});
451461
parent.add(oneof);
@@ -459,14 +469,12 @@ function parse(source, root, options) {
459469
throw illegal(name, "name");
460470

461471
var enm = new Enum(name);
462-
ifBlock(enm, function() {
463-
while ((token = next()) !== "}") {
464-
if (token === "option") {
465-
parseOption(enm, token);
466-
skip(";");
467-
} else
468-
parseEnumValue(enm, token);
469-
}
472+
ifBlock(enm, function parseEnum_block(token) {
473+
if (token === "option") {
474+
parseOption(enm, token);
475+
skip(";");
476+
} else
477+
parseEnumValue(enm, token);
470478
});
471479
parent.add(enm);
472480
}
@@ -480,11 +488,18 @@ function parse(source, root, options) {
480488
var name = token;
481489
skip("=");
482490
var value = parseId(next(), true),
483-
trailingLine = tn.line();
484-
parent.add(name, value, cmnt()); // block-type only
485-
parseInlineOptions({}); // skips enum value options
486-
if (!parent.comments[name])
487-
parent.comments[name] = cmnt(trailingLine);
491+
dummy = {};
492+
ifBlock(dummy, function parseEnumValue_block(token) {
493+
/* istanbul ignore else */
494+
if (token === "option") {
495+
parseOption(dummy, token); // skip
496+
skip(";");
497+
} else
498+
throw illegal(token);
499+
}, function parseEnumValue_line() {
500+
parseInlineOptions(dummy); // skip
501+
});
502+
parent.add(name, value, dummy.comment);
488503
}
489504

490505
function parseOption(parent, token) {
@@ -538,7 +553,6 @@ function parse(source, root, options) {
538553
} while (skip(",", true));
539554
skip("]");
540555
}
541-
skip(";");
542556
return parent;
543557
}
544558

@@ -550,21 +564,19 @@ function parse(source, root, options) {
550564
throw illegal(token, "service name");
551565

552566
var service = new Service(token);
553-
ifBlock(service, function() {
554-
while ((token = next()) !== "}") {
555-
switch (token) {
556-
case "option":
557-
parseOption(service, token);
558-
skip(";");
559-
break;
560-
case "rpc":
561-
parseMethod(service, token);
562-
break;
567+
ifBlock(service, function parseService_block(token) {
568+
switch (token) {
569+
case "option":
570+
parseOption(service, token);
571+
skip(";");
572+
break;
573+
case "rpc":
574+
parseMethod(service, token);
575+
break;
563576

564-
/* istanbul ignore next */
565-
default:
566-
throw illegal(token);
567-
}
577+
/* istanbul ignore next */
578+
default:
579+
throw illegal(token);
568580
}
569581
});
570582
parent.add(service);
@@ -596,20 +608,13 @@ function parse(source, root, options) {
596608
responseType = token;
597609
skip(")");
598610
var method = new Method(name, type, requestType, responseType, requestStream, responseStream);
599-
ifBlock(method, function() {
600-
while ((token = next()) !== "}") {
601-
switch (token) {
602-
603-
case "option":
604-
parseOption(method, token);
605-
skip(";");
606-
break;
607-
608-
/* istanbul ignore next */
609-
default:
610-
throw illegal(token);
611-
}
612-
}
611+
ifBlock(method, function parseMethod_block(token) {
612+
/* istanbul ignore else */
613+
if (token === "option") {
614+
parseOption(method, token);
615+
skip(";");
616+
} else
617+
throw illegal(token);
613618
});
614619
parent.add(method);
615620
}
@@ -621,26 +626,24 @@ function parse(source, root, options) {
621626
if (!typeRefRe.test(reference))
622627
throw illegal(reference, "reference");
623628

624-
if (skip("{", true)) {
625-
while ((token = next()) !== "}") {
626-
switch (token) {
627-
case "required":
628-
case "repeated":
629-
case "optional":
630-
parseField(parent, token, reference);
631-
break;
632-
default:
633-
/* istanbul ignore next */
634-
if (!isProto3 || !typeRefRe.test(token))
635-
throw illegal(token);
636-
push(token);
637-
parseField(parent, "optional", reference);
638-
break;
639-
}
629+
ifBlock(null, function parseExtension_block(token) {
630+
switch (token) {
631+
632+
case "required":
633+
case "repeated":
634+
case "optional":
635+
parseField(parent, token, reference);
636+
break;
637+
638+
default:
639+
/* istanbul ignore next */
640+
if (!isProto3 || !typeRefRe.test(token))
641+
throw illegal(token);
642+
push(token);
643+
parseField(parent, "optional", reference);
644+
break;
640645
}
641-
skip(";", true);
642-
} else
643-
skip(";");
646+
});
644647
}
645648

646649
var token;

0 commit comments

Comments
 (0)