@@ -79,8 +79,20 @@ Root.fromDescriptor = function fromDescriptor(descriptor) {
7979 return root ;
8080} ;
8181
82+ /**
83+ * Converts a root to a descriptor set.
84+ * @returns {Message<FileDescriptorSetProperties> } Descriptor
85+ * @param {string } [syntax="proto2"] Syntax
86+ * @see Part of the {@link descriptor} extension (ext/descriptor)
87+ */
88+ Root . prototype . toDescriptor = function toDescriptor ( syntax ) {
89+ var set = exports . FileDescriptorSet . create ( ) ;
90+ Root_toDescriptorRecursive ( this , set . file , syntax ) ;
91+ return set ;
92+ } ;
93+
8294// Traverses a namespace and assembles the descriptor set
83- function traverseNamespace ( ns , files , syntax ) {
95+ function Root_toDescriptorRecursive ( ns , files , syntax ) {
8496
8597 // Create a new file
8698 var file = exports . FileDescriptorProto . create ( { name : ns . filename || ( ns . fullName . substring ( 1 ) . replace ( / \. / g, "_" ) || "root" ) + ".proto" } ) ;
@@ -100,25 +112,13 @@ function traverseNamespace(ns, files, syntax) {
100112 else if ( nested instanceof Service )
101113 file . service . push ( nested . toDescriptor ( ) ) ;
102114 else if ( nested instanceof /* plain */ Namespace )
103- traverseNamespace ( nested , files , syntax ) ; // requires new file
115+ Root_toDescriptorRecursive ( nested , files , syntax ) ; // requires new file
104116
105117 // And keep the file only if there is at least one nested object
106118 if ( file . messageType . length + file . enumType . length + file . extension . length + file . service . length )
107119 files . push ( file ) ;
108120}
109121
110- /**
111- * Converts a root to a descriptor set.
112- * @returns {Message<FileDescriptorSetProperties> } Descriptor
113- * @param {string } [syntax="proto2"] Syntax
114- * @see Part of the {@link descriptor} extension (ext/descriptor)
115- */
116- Root . prototype . toDescriptor = function toDescriptor ( syntax ) {
117- var set = exports . FileDescriptorSet . create ( ) ;
118- traverseNamespace ( this , set . file , syntax ) ;
119- return set ;
120- } ;
121-
122122// --- Type ---
123123
124124/**
@@ -183,15 +183,19 @@ Type.fromDescriptor = function fromDescriptor(descriptor, syntax) {
183183 var type = new Type ( descriptor . name . length ? descriptor . name : "Type" + unnamedMessageIndex ++ ) ,
184184 i ;
185185
186+ /* Oneofs */ if ( descriptor . oneofDecl )
187+ for ( i = 0 ; i < descriptor . oneofDecl . length ; ++ i )
188+ type . add ( OneOf . fromDescriptor ( descriptor . oneofDecl [ i ] ) ) ;
186189 /* Fields */ if ( descriptor . field )
187- for ( i = 0 ; i < descriptor . field . length ; ++ i )
188- type . add ( Field . fromDescriptor ( descriptor . field [ i ] , syntax ) ) ;
190+ for ( i = 0 ; i < descriptor . field . length ; ++ i ) {
191+ var field = Field . fromDescriptor ( descriptor . field [ i ] , syntax ) ;
192+ type . add ( field ) ;
193+ if ( descriptor . field [ i ] . hasOwnProperty ( "oneofIndex" ) ) // eslint-disable-line no-prototype-builtins
194+ type . oneofsArray [ descriptor . field [ i ] . oneofIndex ] . add ( field ) ;
195+ }
189196 /* Extension fields */ if ( descriptor . extension )
190197 for ( i = 0 ; i < descriptor . extension . length ; ++ i )
191198 type . add ( Field . fromDescriptor ( descriptor . extension [ i ] , syntax ) ) ;
192- /* Oneofs */ if ( descriptor . oneofDecl )
193- for ( i = 0 ; i < descriptor . oneofDecl . length ; ++ i )
194- type . add ( OneOf . fromDescriptor ( descriptor . oneofDecl [ i ] ) ) ;
195199 /* Nested types */ if ( descriptor . nestedType )
196200 for ( i = 0 ; i < descriptor . nestedType . length ; ++ i ) {
197201 type . add ( Type . fromDescriptor ( descriptor . nestedType [ i ] , syntax ) ) ;
@@ -230,15 +234,16 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) {
230234 i ;
231235
232236 /* Fields */ for ( i = 0 ; i < this . fieldsArray . length ; ++ i ) {
233- descriptor . field . push ( this . _fieldsArray [ i ] . toDescriptor ( syntax ) ) ;
237+ var fieldDescriptor ;
238+ descriptor . field . push ( fieldDescriptor = this . _fieldsArray [ i ] . toDescriptor ( syntax ) ) ;
234239 if ( this . _fieldsArray [ i ] instanceof MapField ) { // map fields are repeated FieldNameEntry
235240 var keyType = toDescriptorType ( this . _fieldsArray [ i ] . keyType , this . _fieldsArray [ i ] . resolvedKeyType ) ,
236241 valueType = toDescriptorType ( this . _fieldsArray [ i ] . type , this . _fieldsArray [ i ] . resolvedType ) ,
237242 valueTypeName = valueType === /* type */ 11 || valueType === /* enum */ 14
238- ? this . _fieldsArray [ i ] . resolvedType && this . _fieldsArray [ i ] . resolvedType . fullName || this . _fieldsArray [ i ] . type
243+ ? this . _fieldsArray [ i ] . resolvedType && shortname ( this . parent , this . _fieldsArray [ i ] . resolvedType ) || this . _fieldsArray [ i ] . type
239244 : undefined ;
240245 descriptor . nestedType . push ( exports . DescriptorProto . create ( {
241- name : descriptor . field [ descriptor . field . length - 1 ] . typeName ,
246+ name : fieldDescriptor . typeName ,
242247 field : [
243248 exports . FieldDescriptorProto . create ( { name : "key" , number : 1 , label : 1 , type : keyType } ) , // can't reference a type or enum
244249 exports . FieldDescriptorProto . create ( { name : "value" , number : 2 , label : 1 , type : valueType , typeName : valueTypeName } )
@@ -247,11 +252,11 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) {
247252 } ) ) ;
248253 }
249254 }
255+ /* Oneofs */ for ( i = 0 ; i < this . oneofsArray . length ; ++ i )
256+ descriptor . oneofDecl . push ( this . _oneofsArray [ i ] . toDescriptor ( ) ) ;
250257 /* Nested... */ for ( i = 0 ; i < this . nestedArray . length ; ++ i ) {
251258 /* Extension fields */ if ( this . _nestedArray [ i ] instanceof Field )
252259 descriptor . field . push ( this . _nestedArray [ i ] . toDescriptor ( syntax ) ) ;
253- /* Oneofs */ else if ( this . _nestedArray [ i ] instanceof OneOf )
254- descriptor . oneofDecl . push ( this . _nestedArray [ i ] . toDescriptor ( ) ) ;
255260 /* Types */ else if ( this . _nestedArray [ i ] instanceof Type )
256261 descriptor . nestedType . push ( this . _nestedArray [ i ] . toDescriptor ( syntax ) ) ;
257262 /* Enums */ else if ( this . _nestedArray [ i ] instanceof Enum )
@@ -286,7 +291,7 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) {
286291 * @property {FieldDescriptorProto_Type } [type] Field basic type
287292 * @property {string } [typeName] Field type name
288293 * @property {string } [extendee] Extended type name
289- * @property {* } [defaultValue] Not supported
294+ * @property {string } [defaultValue] Literal default value
290295 * @property {number } [oneofIndex] Oneof index if part of a oneof
291296 * @property {* } [jsonName] Not supported
292297 * @property {FieldOptionsProperties } [options] Field options
@@ -346,51 +351,6 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) {
346351 * @property {number } JS_NUMBER=2
347352 */
348353
349- // Converts a descriptor type to a protobuf.js basic type
350- function fromDescriptorType ( type ) {
351- switch ( type ) {
352- // 0 is reserved for errors
353- case 1 : return "double" ;
354- case 2 : return "float" ;
355- case 3 : return "int64" ;
356- case 4 : return "uint64" ;
357- case 5 : return "int32" ;
358- case 6 : return "fixed64" ;
359- case 7 : return "fixed32" ;
360- case 8 : return "bool" ;
361- case 9 : return "string" ;
362- case 12 : return "bytes" ;
363- case 13 : return "uint32" ;
364- case 15 : return "sfixed32" ;
365- case 16 : return "sfixed64" ;
366- case 17 : return "sint32" ;
367- case 18 : return "sint64" ;
368- }
369- throw Error ( "illegal type: " + type ) ;
370- }
371-
372- // Tests if a descriptor type is packable
373- function packableDescriptorType ( type ) {
374- switch ( type ) {
375- case 1 : // double
376- case 2 : // float
377- case 3 : // int64
378- case 4 : // uint64
379- case 5 : // int32
380- case 6 : // fixed64
381- case 7 : // fixed32
382- case 8 : // bool
383- case 13 : // uint32
384- case 14 : // enum (!)
385- case 15 : // sfixed32
386- case 16 : // sfixed64
387- case 17 : // sint32
388- case 18 : // sint64
389- return true ;
390- }
391- return false ;
392- }
393-
394354/**
395355 * Creates a field from a descriptor.
396356 * @param {FieldDescriptorProtoProperties|Reader|Uint8Array } descriptor Descriptor
@@ -434,6 +394,8 @@ Field.fromDescriptor = function fromDescriptor(descriptor, syntax) {
434394
435395 if ( descriptor . options )
436396 field . options = fromDescriptorOptions ( descriptor . options , exports . FieldOptions ) ;
397+ if ( descriptor . defaultValue && descriptor . defaultValue . length )
398+ field . setOption ( "default" , descriptor . defaultValue ) ;
437399
438400 if ( packableDescriptorType ( descriptor . type ) ) {
439401 if ( syntax === "proto3" ) { // defaults to packed=true (internal preset is packed=true)
@@ -446,33 +408,6 @@ Field.fromDescriptor = function fromDescriptor(descriptor, syntax) {
446408 return field ;
447409} ;
448410
449- // Converts a protobuf.js basic type to a descriptor type
450- function toDescriptorType ( type , resolvedType ) {
451- switch ( type ) {
452- // 0 is reserved for errors
453- case "double" : return 1 ;
454- case "float" : return 2 ;
455- case "int64" : return 3 ;
456- case "uint64" : return 4 ;
457- case "int32" : return 5 ;
458- case "fixed64" : return 6 ;
459- case "fixed32" : return 7 ;
460- case "bool" : return 8 ;
461- case "string" : return 9 ;
462- case "bytes" : return 12 ;
463- case "uint32" : return 13 ;
464- case "sfixed32" : return 15 ;
465- case "sfixed64" : return 16 ;
466- case "sint32" : return 17 ;
467- case "sint64" : return 18 ;
468- }
469- if ( resolvedType instanceof Enum )
470- return 14 ;
471- if ( resolvedType instanceof Type )
472- return resolvedType . group ? 10 : 11 ;
473- throw Error ( "illegal type: " + type ) ;
474- }
475-
476411/**
477412 * Converts a field to a descriptor.
478413 * @returns {Message<FieldDescriptorProtoProperties> } Descriptor
@@ -495,7 +430,7 @@ Field.prototype.toDescriptor = function toDescriptor(syntax) {
495430 case 10 : // group
496431 case 11 : // type
497432 case 14 : // enum
498- descriptor . typeName = this . resolvedType ? this . resolvedType . fullName : this . type ; // TODO: shorten
433+ descriptor . typeName = this . resolvedType ? shortname ( this . parent , this . resolvedType ) : this . type ;
499434 break ;
500435 }
501436
@@ -516,8 +451,11 @@ Field.prototype.toDescriptor = function toDescriptor(syntax) {
516451 if ( ( descriptor . oneofIndex = this . parent . oneofsArray . indexOf ( this . partOf ) ) < 0 )
517452 throw Error ( "missing oneof" ) ;
518453
519- if ( this . options )
454+ if ( this . options ) {
520455 descriptor . options = toDescriptorOptions ( this . options , exports . FieldOptions ) ;
456+ if ( this . options [ "default" ] != null )
457+ descriptor . defaultValue = String ( this . options [ "default" ] ) ;
458+ }
521459
522460 if ( syntax === "proto3" ) { // defaults to packed=true
523461 if ( ! this . packed )
@@ -757,6 +695,79 @@ Method.prototype.toDescriptor = function toDescriptor() {
757695
758696// --- utility ---
759697
698+ // Converts a descriptor type to a protobuf.js basic type
699+ function fromDescriptorType ( type ) {
700+ switch ( type ) {
701+ // 0 is reserved for errors
702+ case 1 : return "double" ;
703+ case 2 : return "float" ;
704+ case 3 : return "int64" ;
705+ case 4 : return "uint64" ;
706+ case 5 : return "int32" ;
707+ case 6 : return "fixed64" ;
708+ case 7 : return "fixed32" ;
709+ case 8 : return "bool" ;
710+ case 9 : return "string" ;
711+ case 12 : return "bytes" ;
712+ case 13 : return "uint32" ;
713+ case 15 : return "sfixed32" ;
714+ case 16 : return "sfixed64" ;
715+ case 17 : return "sint32" ;
716+ case 18 : return "sint64" ;
717+ }
718+ throw Error ( "illegal type: " + type ) ;
719+ }
720+
721+ // Tests if a descriptor type is packable
722+ function packableDescriptorType ( type ) {
723+ switch ( type ) {
724+ case 1 : // double
725+ case 2 : // float
726+ case 3 : // int64
727+ case 4 : // uint64
728+ case 5 : // int32
729+ case 6 : // fixed64
730+ case 7 : // fixed32
731+ case 8 : // bool
732+ case 13 : // uint32
733+ case 14 : // enum (!)
734+ case 15 : // sfixed32
735+ case 16 : // sfixed64
736+ case 17 : // sint32
737+ case 18 : // sint64
738+ return true ;
739+ }
740+ return false ;
741+ }
742+
743+ // Converts a protobuf.js basic type to a descriptor type
744+ function toDescriptorType ( type , resolvedType ) {
745+ switch ( type ) {
746+ // 0 is reserved for errors
747+ case "double" : return 1 ;
748+ case "float" : return 2 ;
749+ case "int64" : return 3 ;
750+ case "uint64" : return 4 ;
751+ case "int32" : return 5 ;
752+ case "fixed64" : return 6 ;
753+ case "fixed32" : return 7 ;
754+ case "bool" : return 8 ;
755+ case "string" : return 9 ;
756+ case "bytes" : return 12 ;
757+ case "uint32" : return 13 ;
758+ case "sfixed32" : return 15 ;
759+ case "sfixed64" : return 16 ;
760+ case "sint32" : return 17 ;
761+ case "sint64" : return 18 ;
762+ }
763+ if ( resolvedType instanceof Enum )
764+ return 14 ;
765+ if ( resolvedType instanceof Type )
766+ return resolvedType . group ? 10 : 11 ;
767+ throw Error ( "illegal type: " + type ) ;
768+ }
769+
770+ // Converts descriptor options to an options object
760771function fromDescriptorOptions ( options , type ) {
761772 var out = [ ] ;
762773 for ( var i = 0 , key ; i < type . fieldsArray . length ; ++ i )
@@ -766,13 +777,34 @@ function fromDescriptorOptions(options, type) {
766777 return out . length ? $protobuf . util . toObject ( out ) : undefined ;
767778}
768779
780+ // Converts an options object to descriptor options
769781function toDescriptorOptions ( options , type ) {
770782 var out = [ ] ;
771783 for ( var i = 0 , key ; i < type . fieldsArray . length ; ++ i )
772- out . push ( key = type . _fieldsArray [ i ] . name , options [ key ] ) ;
784+ if ( ( key = type . _fieldsArray [ i ] . name ) !== "default" )
785+ out . push ( key , options [ key ] ) ;
773786 return out . length ? type . fromObject ( $protobuf . util . toObject ( out ) ) : undefined ;
774787}
775788
789+ // Calculates the shortest relative path from `from` to `to`.
790+ function shortname ( from , to ) {
791+ var fromPath = from . fullName . split ( "." ) ,
792+ toPath = to . fullName . split ( "." ) ,
793+ i = 0 ,
794+ j = 0 ,
795+ k = toPath . length - 1 ;
796+ if ( ! ( from instanceof Root ) && to instanceof Namespace )
797+ while ( i < fromPath . length && j < k && fromPath [ i ] === toPath [ j ] ) {
798+ var other = to . lookup ( fromPath [ i ++ ] , true ) ;
799+ if ( other !== null && other !== to )
800+ break ;
801+ ++ j ;
802+ }
803+ else
804+ for ( ; i < fromPath . length && j < k && fromPath [ i ] === toPath [ j ] ; ++ i , ++ j ) ;
805+ return toPath . slice ( j ) . join ( "." ) ;
806+ }
807+
776808// --- exports ---
777809
778810/**
0 commit comments