Skip to content

Commit 6c37dbd

Browse files
committed
Other: Added still missing root traversal to ext/descriptor, see #757
1 parent 7ab136d commit 6c37dbd

File tree

2 files changed

+63
-29
lines changed

2 files changed

+63
-29
lines changed

ext/descriptor/index.d.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ interface IDescriptorProto {
3535
}
3636

3737
interface IMessageOptions {
38-
mapEntry?: any;
38+
mapEntry?: boolean;
3939
}
4040

4141
interface IExtensionRange {
@@ -48,6 +48,10 @@ interface IReservedRange {
4848
end?: number;
4949
}
5050

51+
interface IFieldOptions {
52+
packed?: boolean;
53+
}
54+
5155
interface IFieldDescriptorProto {
5256
name?: string;
5357
number?: number;
@@ -65,10 +69,6 @@ type IFieldDescriptorProto_Label = number;
6569

6670
type IFieldDescriptorProto_Type = number;
6771

68-
interface IFieldOptions {
69-
packed?: boolean;
70-
}
71-
7272
interface IEnumDescriptorProto {
7373
name?: string;
7474
value?: IEnumValueDescriptorProto[];

ext/descriptor/index.js

+58-24
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ var $protobuf = require("..");
1212
*/
1313
var 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
*/
104144
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;
114148
};
115149

116150
// --- Type ---

0 commit comments

Comments
 (0)