protobuf.js version: <6.6.4>
i want to collect all the message names in a map, like below:
syntax = "proto3";
import "target.proto";
import "image.proto";
import ...
package protobuf;
message AcceptVoipRequest {
Target target = 1; // ç›®æ ‡
}
// all my .proto files just like above
function getMessageName(proto) {
let name
// how to do this?
// here name = 'AcceptVoipRequest'
return name
}
protoNames.forEach(name => {
let filePath = path.join(protoDir, name)
let proto = ProtoBuf.loadSync(filePath)
map[getMessageName(proto)] = proto
})
Ideally, you'd just traverse through the root instance by calling a function with your logic for each message type within:
function traverseTypes(current, fn) {
if (current instanceof protobuf.Type)
fn(current);
if (current.nestedArray)
current.nestedArray.forEach(function(nested) {
traverseTypes(nested, fn);
});
}
Example:
var root = protobuf.loadSync(...);
traverseTypes(root, function(type) {
console.log(type.fullName);
});
See also: API of protobuf.Type
Also created an example.
@dcodeIO that's not what i really want, your code above will display all the message names that a .proto file have(or imports). but i only want display the single name without any imports(for example i only want display the name: 'AcceptVoipRequest').
A Root instance always contains all types of messages loaded into it. To find a specific message within a specific file, you'd either have to examine that exact file, i.e. using a regular expression
var source = ...;
var re = /\bmessage\s+(\w+) /g;
var match;
while (match = re.exec(source)) {
console.log(match[1]);
}
or to annotate the messages you'd like to expose in some way understood by reflection, so you can filter.
message AcceptVoipRequest {
option someOption = true;
Target target = 1; // ç›®æ ‡
}
traverseTypes(root, function(type) {
if (type.options && type.options.someOption)
console.log(type.fullName);
});
Additionally, reflection objects (messages, enums, services etc.) also have a filename property that you could use.
traverseTypes(root, function(type) {
if (/\bAcceptVoipRequest\.proto$/.test(type.filename))
console.log(type.fullName);
});
Likewise, all loaded files are present within Root#files (a string array).
See also: Updated example
@dcodeIO thanks a lot for your patience and help. Examine the exact file or the filename is fit for me. I finally solved this problem by examine the filename and fllow some rules of convention。