@@ -125,3 +125,119 @@ exports.pad = function(str, len, l) {
125125 return str ;
126126} ;
127127
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