@@ -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