@@ -12,15 +12,16 @@ var $protobuf = require("..");
12
12
*/
13
13
var descriptor = module . exports = $protobuf . Root . fromJSON ( require ( "../google/protobuf/descriptor.json" ) ) . lookup ( ".google.protobuf" ) ;
14
14
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 ;
24
25
25
26
// --- Root ---
26
27
@@ -87,12 +88,51 @@ Root.fromDescriptor = function fromDescriptor(descriptor) {
87
88
return root ;
88
89
} ;
89
90
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
+ }
96
136
}
97
137
98
138
/**
@@ -102,15 +142,9 @@ function traverseNamespace(ns, file) {
102
142
* @see Part of the {@link descriptor} extension (ext/descriptor)
103
143
*/
104
144
Root . 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 ;
114
148
} ;
115
149
116
150
// --- Type ---
0 commit comments