11"use strict" ;
2- var $protobuf = require ( "../.." ) ;
2+ var $protobuf = require ( "../.." ) ; // requires the full library (uses parser exports)
33module . exports = exports = $protobuf . descriptor = $protobuf . Root . fromJSON ( require ( "../../google/protobuf/descriptor.json" ) ) . lookup ( ".google.protobuf" ) ;
44
55var Namespace = $protobuf . Namespace ,
@@ -73,6 +73,12 @@ Root.fromDescriptor = function fromDescriptor(descriptor) {
7373 if ( fileDescriptor . extension )
7474 for ( i = 0 ; i < fileDescriptor . extension . length ; ++ i )
7575 filePackage . add ( Field . fromDescriptor ( fileDescriptor . extension [ i ] ) ) ;
76+ var opts = fromDescriptorOptions ( fileDescriptor . options , exports . FileOptions ) ;
77+ if ( opts ) {
78+ var ks = Object . keys ( opts ) ;
79+ for ( i = 0 ; i < ks . length ; ++ i )
80+ filePackage . setOption ( ks [ i ] , opts [ ks [ i ] ] ) ;
81+ }
7682 }
7783 }
7884
@@ -114,6 +120,9 @@ function Root_toDescriptorRecursive(ns, files, syntax) {
114120 else if ( nested instanceof /* plain */ Namespace )
115121 Root_toDescriptorRecursive ( nested , files , syntax ) ; // requires new file
116122
123+ // Keep package-level options
124+ file . options = toDescriptorOptions ( ns . options , exports . FileOptions ) ;
125+
117126 // And keep the file only if there is at least one nested object
118127 if ( file . messageType . length + file . enumType . length + file . extension . length + file . service . length )
119128 files . push ( file ) ;
@@ -180,7 +189,7 @@ Type.fromDescriptor = function fromDescriptor(descriptor, syntax) {
180189 descriptor = exports . DescriptorProto . decode ( descriptor ) ;
181190
182191 // Create the message type
183- var type = new Type ( descriptor . name . length ? descriptor . name : "Type" + unnamedMessageIndex ++ ) ,
192+ var type = new Type ( descriptor . name . length ? descriptor . name : "Type" + unnamedMessageIndex ++ , fromDescriptorOptions ( descriptor . options , exports . MessageOptions ) ) ,
184193 i ;
185194
186195 /* Oneofs */ if ( descriptor . oneofDecl )
@@ -273,8 +282,7 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) {
273282 /* Ranges */ else
274283 descriptor . reservedRange . push ( exports . DescriptorProto . ReservedRange . create ( { start : this . reserved [ i ] [ 0 ] , end : this . reserved [ i ] [ 1 ] } ) ) ;
275284
276- if ( this . options && this . options . map_entry )
277- descriptor . options = exports . MessageOptions . create ( { map_entry : true } ) ;
285+ descriptor . options = toDescriptorOptions ( this . options , exports . MessageOptions ) ;
278286
279287 return descriptor ;
280288} ;
@@ -392,10 +400,25 @@ Field.fromDescriptor = function fromDescriptor(descriptor, syntax) {
392400 descriptor . extendee . length ? descriptor . extendee : undefined
393401 ) ;
394402
395- if ( descriptor . options )
396- field . options = fromDescriptorOptions ( descriptor . options , exports . FieldOptions ) ;
397- if ( descriptor . defaultValue && descriptor . defaultValue . length )
398- field . setOption ( "default" , descriptor . defaultValue ) ;
403+ field . options = fromDescriptorOptions ( descriptor . options , exports . FieldOptions ) ;
404+
405+ if ( descriptor . defaultValue && descriptor . defaultValue . length ) {
406+ var defaultValue = descriptor . defaultValue ;
407+ switch ( defaultValue ) {
408+ case "true" : case "TRUE" :
409+ defaultValue = true ;
410+ break ;
411+ case "false" : case "FALSE" :
412+ defaultValue = false ;
413+ break ;
414+ default :
415+ var match = $protobuf . parse . numberRe . exec ( defaultValue ) ;
416+ if ( match )
417+ defaultValue = parseInt ( defaultValue ) ;
418+ break ;
419+ }
420+ field . setOption ( "default" , defaultValue ) ;
421+ }
399422
400423 if ( packableDescriptorType ( descriptor . type ) ) {
401424 if ( syntax === "proto3" ) { // defaults to packed=true (internal preset is packed=true)
@@ -522,7 +545,7 @@ Enum.fromDescriptor = function fromDescriptor(descriptor) {
522545 return new Enum (
523546 descriptor . name && descriptor . name . length ? descriptor . name : "Enum" + unnamedEnumIndex ++ ,
524547 values ,
525- descriptor . options && descriptor . options . allowAlias ? { allowAlias : true } : undefined
548+ fromDescriptorOptions ( descriptor . options , exports . EnumOptions )
526549 ) ;
527550} ;
528551
@@ -540,7 +563,8 @@ Enum.prototype.toDescriptor = function toDescriptor() {
540563
541564 return exports . EnumDescriptorProto . create ( {
542565 name : this . name ,
543- value : values
566+ value : values ,
567+ options : toDescriptorOptions ( this . options , exports . EnumOptions )
544568 } ) ;
545569} ;
546570
@@ -572,6 +596,7 @@ OneOf.fromDescriptor = function fromDescriptor(descriptor) {
572596 return new OneOf (
573597 // unnamedOneOfIndex is global, not per type, because we have no ref to a type here
574598 descriptor . name && descriptor . name . length ? descriptor . name : "oneof" + unnamedOneofIndex ++
599+ // fromDescriptorOptions(descriptor.options, exports.OneofOptions) - only uninterpreted_option
575600 ) ;
576601} ;
577602
@@ -583,6 +608,7 @@ OneOf.fromDescriptor = function fromDescriptor(descriptor) {
583608OneOf . prototype . toDescriptor = function toDescriptor ( ) {
584609 return exports . OneofDescriptorProto . create ( {
585610 name : this . name
611+ // options: toDescriptorOptions(this.options, exports.OneofOptions) - only uninterpreted_option
586612 } ) ;
587613} ;
588614
@@ -612,7 +638,7 @@ Service.fromDescriptor = function fromDescriptor(descriptor) {
612638 if ( typeof descriptor . length === "number" )
613639 descriptor = exports . ServiceDescriptorProto . decode ( descriptor ) ;
614640
615- var service = new Service ( descriptor . name && descriptor . name . length ? descriptor . name : "Service" + unnamedServiceIndex ++ ) ;
641+ var service = new Service ( descriptor . name && descriptor . name . length ? descriptor . name : "Service" + unnamedServiceIndex ++ , fromDescriptorOptions ( descriptor . options , exports . ServiceOptions ) ) ;
616642 if ( descriptor . method )
617643 for ( var i = 0 ; i < descriptor . method . length ; ++ i )
618644 service . add ( Method . fromDescriptor ( descriptor . method [ i ] ) ) ;
@@ -634,7 +660,8 @@ Service.prototype.toDescriptor = function toDescriptor() {
634660
635661 return exports . ServiceDescriptorProto . create ( {
636662 name : this . name ,
637- methods : methods
663+ methods : methods ,
664+ options : toDescriptorOptions ( this . options , exports . ServiceOptions )
638665 } ) ;
639666} ;
640667
@@ -674,7 +701,8 @@ Method.fromDescriptor = function fromDescriptor(descriptor) {
674701 descriptor . inputType ,
675702 descriptor . outputType ,
676703 Boolean ( descriptor . clientStreaming ) ,
677- Boolean ( descriptor . serverStreaming )
704+ Boolean ( descriptor . serverStreaming ) ,
705+ fromDescriptorOptions ( descriptor . options , exports . MethodOptions )
678706 ) ;
679707} ;
680708
@@ -689,7 +717,8 @@ Method.prototype.toDescriptor = function toDescriptor() {
689717 inputType : this . resolvedRequestType ? this . resolvedRequestType . fullName : this . requestType ,
690718 outputType : this . resolvedResponseType ? this . resolvedResponseType . fullName : this . responseType ,
691719 clientStreaming : this . requestStream ,
692- serverStreaming : this . responseStream
720+ serverStreaming : this . responseStream ,
721+ options : toDescriptorOptions ( this . options , exports . MethodOptions )
693722 } ) ;
694723} ;
695724
@@ -769,20 +798,34 @@ function toDescriptorType(type, resolvedType) {
769798
770799// Converts descriptor options to an options object
771800function fromDescriptorOptions ( options , type ) {
801+ if ( ! options )
802+ return undefined ;
772803 var out = [ ] ;
773- for ( var i = 0 , key ; i < type . fieldsArray . length ; ++ i )
774- if ( ( key = type . _fieldsArray [ i ] . name ) !== "uninterpretedOption" )
775- if ( options . hasOwnProperty ( key ) ) // eslint-disable-line no-prototype-builtins
776- out . push ( key , options [ key ] ) ;
804+ for ( var i = 0 , field , key , val ; i < type . fieldsArray . length ; ++ i )
805+ if ( ( key = ( field = type . _fieldsArray [ i ] ) . name ) !== "uninterpretedOption" )
806+ if ( options . hasOwnProperty ( key ) ) { // eslint-disable-line no-prototype-builtins
807+ val = options [ key ] ;
808+ if ( field . resolvedType instanceof Enum && typeof val === "number" && field . resolvedType . valuesById [ val ] !== undefined )
809+ val = field . resolvedType . valuesById [ val ] ;
810+ out . push ( underScore ( key ) , val ) ;
811+ }
777812 return out . length ? $protobuf . util . toObject ( out ) : undefined ;
778813}
779814
780815// Converts an options object to descriptor options
781816function toDescriptorOptions ( options , type ) {
817+ if ( ! options )
818+ return undefined ;
782819 var out = [ ] ;
783- for ( var i = 0 , key ; i < type . fieldsArray . length ; ++ i )
784- if ( ( key = type . _fieldsArray [ i ] . name ) !== "default" )
785- out . push ( key , options [ key ] ) ;
820+ for ( var i = 0 , ks = Object . keys ( options ) , key , val ; i < ks . length ; ++ i ) {
821+ val = options [ key = ks [ i ] ] ;
822+ if ( key === "default" )
823+ continue ;
824+ var field = type . fields [ key ] ;
825+ if ( ! field && ! ( field = type . fields [ key = $protobuf . parse . camelCase ( key ) ] ) )
826+ continue ;
827+ out . push ( key , val ) ;
828+ }
786829 return out . length ? type . fromObject ( $protobuf . util . toObject ( out ) ) : undefined ;
787830}
788831
@@ -805,6 +848,13 @@ function shortname(from, to) {
805848 return toPath . slice ( j ) . join ( "." ) ;
806849}
807850
851+ // copied here from cli/targets/proto.js
852+ function underScore ( str ) {
853+ return str . substring ( 0 , 1 )
854+ + str . substring ( 1 )
855+ . replace ( / ( [ A - Z ] ) (? = [ a - z ] | $ ) / g, function ( $0 , $1 ) { return "_" + $1 . toLowerCase ( ) ; } ) ;
856+ }
857+
808858// --- exports ---
809859
810860/**
0 commit comments