@@ -125,3 +125,119 @@ exports.pad = function(str, len, l) {
125
125
return str ;
126
126
} ;
127
127
128
+
129
+ /**
130
+ * DFS to get all message dependencies, cache in filterMap.
131
+ * @param {Root } root The protobuf root instance
132
+ * @param {Message } message The message need to process.
133
+ * @param {Map } filterMap The result of message you need and their dependencies.
134
+ * @param {Map } flatMap A flag to record whether the message was searched.
135
+ * @returns {undefined } Does not return a value
136
+ */
137
+ function dfsFilterMessageDependencies ( root , message , filterMap , flatMap ) {
138
+ if ( message instanceof protobuf . Type ) {
139
+ if ( flatMap . get ( `${ message . fullName } ` ) ) return ;
140
+ flatMap . set ( `${ message . fullName } ` , true ) ;
141
+ for ( var field of message . fieldsArray ) {
142
+ if ( field . resolvedType ) {
143
+ // a nested message
144
+ if ( field . resolvedType . parent . name === message . name ) {
145
+ var nestedMessage = message . nested [ field . resolvedType . name ] ;
146
+ dfsFilterMessageDependencies ( root , nestedMessage , filterMap , flatMap ) ;
147
+ continue ;
148
+ }
149
+ var packageName = field . resolvedType . parent . name ;
150
+ var typeName = field . resolvedType . name ;
151
+ var fullName = packageName ? `${ packageName } .${ typeName } ` : typeName ;
152
+ doFilterMessage ( root , { messageNames : [ fullName ] } , filterMap , flatMap , packageName ) ;
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ * DFS to get all message you need and their dependencies, cache in filterMap.
160
+ * @param {Root } root The protobuf root instance
161
+ * @param {object } needMessageConfig Need message config:
162
+ * @param {string[] } needMessageConfig.messageNames The message names array in the root namespace you need to gen. example: [msg1, msg2]
163
+ * @param {Map } filterMap The result of message you need and their dependencies.
164
+ * @param {Map } flatMap A flag to record whether the message was searched.
165
+ * @param {string } currentPackageName Current package name
166
+ * @returns {undefined } Does not return a value
167
+ */
168
+ function doFilterMessage ( root , needMessageConfig , filterMap , flatMap , currentPackageName ) {
169
+ var needMessageNames = needMessageConfig . messageNames ;
170
+
171
+ for ( var messageFullName of needMessageNames ) {
172
+ var nameSplit = messageFullName . split ( "." ) ;
173
+ var packageName = "" ;
174
+ var messageName = "" ;
175
+ if ( nameSplit . length > 1 ) {
176
+ packageName = nameSplit [ 0 ] ;
177
+ messageName = nameSplit [ 1 ] ;
178
+ } else {
179
+ messageName = nameSplit [ 0 ] ;
180
+ }
181
+
182
+ // in Namespace
183
+ if ( packageName ) {
184
+ var ns = root . nested [ packageName ] ;
185
+ if ( ! ns || ! ( ns instanceof protobuf . Namespace ) ) {
186
+ throw new Error ( `package not foud ${ currentPackageName } .${ messageName } ` ) ;
187
+ }
188
+
189
+ doFilterMessage ( root , { messageNames : [ messageName ] } , filterMap , flatMap , packageName ) ;
190
+ } else {
191
+ var message = root . nested [ messageName ] ;
192
+
193
+ if ( currentPackageName ) {
194
+ message = root . nested [ currentPackageName ] . nested [ messageName ] ;
195
+ }
196
+
197
+ if ( ! message ) {
198
+ throw new Error ( `message not foud ${ currentPackageName } .${ messageName } ` ) ;
199
+ }
200
+
201
+ var set = filterMap . get ( currentPackageName ) ;
202
+ if ( ! filterMap . has ( currentPackageName ) ) {
203
+ set = new Set ( ) ;
204
+ filterMap . set ( currentPackageName , set ) ;
205
+ }
206
+
207
+ set . add ( messageName ) ;
208
+
209
+ // dfs to find all dependencies
210
+ dfsFilterMessageDependencies ( root , message , filterMap , flatMap , currentPackageName ) ;
211
+ }
212
+ }
213
+ }
214
+
215
+ /**
216
+ * filter the message you need and their dependencies, all others will be delete from root.
217
+ * @param {Root } root Root the protobuf root instance
218
+ * @param {object } needMessageConfig Need message config:
219
+ * @param {string[] } needMessageConfig.messageNames Tthe message names array in the root namespace you need to gen. example: [msg1, msg2]
220
+ * @returns {boolean } True if a message should present in the generated files
221
+ */
222
+ exports . filterMessage = function ( root , needMessageConfig ) {
223
+ var filterMap = new Map ( ) ;
224
+ var flatMap = new Map ( ) ;
225
+ doFilterMessage ( root , needMessageConfig , filterMap , flatMap , "" ) ;
226
+ root . _nestedArray = root . _nestedArray . filter ( ns => {
227
+ if ( ns instanceof protobuf . Type || ns instanceof protobuf . Enum ) {
228
+ return filterMap . get ( "" ) . has ( ns . name ) ;
229
+ } else if ( ns instanceof protobuf . Namespace ) {
230
+ if ( ! filterMap . has ( ns . name ) ) {
231
+ return false ;
232
+ }
233
+ ns . _nestedArray = ns . _nestedArray . filter ( nns => {
234
+ const nnsSet = filterMap . get ( ns . name ) ;
235
+ return nnsSet . has ( nns . name ) ;
236
+ } ) ;
237
+
238
+ return true ;
239
+ }
240
+ return true ;
241
+ } ) ;
242
+ } ;
243
+
0 commit comments