@@ -12,15 +12,16 @@ var $protobuf = require("..");
1212 */
1313var descriptor = module . exports = $protobuf . Root . fromJSON ( require ( "../google/protobuf/descriptor.json" ) ) . lookup ( ".google.protobuf" ) ;
1414
15- var google = descriptor , // alias used where `descriptor` is a local var
16- Root = $protobuf . Root ,
17- Enum = $protobuf . Enum ,
18- Type = $protobuf . Type ,
19- Field = $protobuf . Field ,
20- MapField = $protobuf . MapField ,
21- OneOf = $protobuf . OneOf ,
22- Service = $protobuf . Service ,
23- Method = $protobuf . Method ;
15+ var google = descriptor , // alias used where `descriptor` is a local var
16+ Namespace = $protobuf . Namespace ,
17+ Root = $protobuf . Root ,
18+ Enum = $protobuf . Enum ,
19+ Type = $protobuf . Type ,
20+ Field = $protobuf . Field ,
21+ MapField = $protobuf . MapField ,
22+ OneOf = $protobuf . OneOf ,
23+ Service = $protobuf . Service ,
24+ Method = $protobuf . Method ;
2425
2526// --- Root ---
2627
@@ -87,12 +88,51 @@ Root.fromDescriptor = function fromDescriptor(descriptor) {
8788 return root ;
8889} ;
8990
90- function traverseNamespace ( ns , file ) {
91- for ( var i = 0 ; i < ns . nestedArray . length ; ++ i )
92- ( ns . _nestedArray [ i ] instanceof Type ? file . messageType
93- : ns . _nestedArray [ i ] instanceof Enum ? file . enumType
94- : ns . _nestedArray [ i ] instanceof Field ? file . extension
95- : ns . _nestedArray [ i ] instanceof Service ? file . service : [ ] ) . push ( ns . _nestedArray [ i ] . toDescriptor ( file . syntax ) ) ;
91+ // Traverses a namespace and assembles the descriptor set
92+ function traverseNamespace ( ns , file , files , syntax ) {
93+
94+ // When encountering a plain namespace, create a new file using the current path as its package,
95+ // but don't add the file yet until we know that it has some actual types.
96+ var newFile = false ;
97+ if ( ns instanceof Namespace && ! ( ns instanceof Type || ns instanceof Service ) ) {
98+ file = google . FileDescriptorProto . create ( {
99+ name : ns . filename || ns . fullName . substring ( 1 ) . replace ( / \. / g, "_" ) + ".proto"
100+ } ) ;
101+ if ( syntax )
102+ file . syntax = syntax ;
103+ if ( ! ( ns instanceof Root ) )
104+ file [ "package" ] = ns . fullName . substring ( 1 ) ;
105+ newFile = true ;
106+ }
107+
108+ var descriptor , which ;
109+ for ( var i = 0 ; i < ns . nestedArray . length ; ++ i ) {
110+ if ( ns . _nestedArray [ i ] . toDescriptor ) {
111+ descriptor = ns . _nestedArray [ i ] . toDescriptor ( file . syntax ) ;
112+ which = null ;
113+ if ( ns . _nestedArray [ i ] instanceof Type )
114+ which = file . messageType ;
115+ else if ( ns . _nestedArray [ i ] instanceof Enum )
116+ which = file . enumType ;
117+ else if ( ns . _nestedArray [ i ] instanceof Field )
118+ which = file . extension ;
119+ else if ( ns . _nestedArray [ i ] instanceof Service )
120+ which = file . service ;
121+ else
122+ throw Error ( "illegal nested type" ) ;
123+
124+ // There's at least one actual type -> keep the file
125+ if ( newFile ) {
126+ files . push ( file ) ;
127+ newFile = false ;
128+ }
129+ which . push ( descriptor ) ;
130+ }
131+
132+ // And traverse into the namespace
133+ if ( ns . _nestedArray [ i ] instanceof Namespace )
134+ traverseNamespace ( ns . _nestedArray [ i ] , file , files ) ;
135+ }
96136}
97137
98138/**
@@ -102,15 +142,9 @@ function traverseNamespace(ns, file) {
102142 * @see Part of the {@link descriptor} extension (ext/descriptor)
103143 */
104144Root . prototype . toDescriptor = function toDescriptor ( syntax ) {
105- var file = google . FileDescriptorProto . create ( { name : "bundle.proto" } ) ;
106- if ( syntax )
107- file . syntax = syntax ;
108- traverseNamespace ( this , file ) ;
109- // return google.FileDescriptorSet.create({ file: [ file ] });
110-
111- // not working, packages need to be split to individual files first because there is no support
112- // for plain namespaces
113- throw Error ( "not implemented" ) ;
145+ var files = google . FileDescriptorSet . create ( ) ;
146+ traverseNamespace ( this , null , files , syntax ) ;
147+ return files ;
114148} ;
115149
116150// --- Type ---
0 commit comments