UNPKG

8.89 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright 2018 gRPC authors.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19Object.defineProperty(exports, "__esModule", { value: true });
20const camelCase = require("lodash.camelcase");
21const Protobuf = require("protobufjs");
22const descriptor = require("protobufjs/ext/descriptor");
23const util_1 = require("./util");
24function isAnyExtension(obj) {
25 return ('@type' in obj) && (typeof obj['@type'] === 'string');
26}
27exports.isAnyExtension = isAnyExtension;
28const descriptorOptions = {
29 longs: String,
30 enums: String,
31 bytes: String,
32 defaults: true,
33 oneofs: true,
34 json: true,
35};
36function joinName(baseName, name) {
37 if (baseName === '') {
38 return name;
39 }
40 else {
41 return baseName + '.' + name;
42 }
43}
44function isHandledReflectionObject(obj) {
45 return (obj instanceof Protobuf.Service ||
46 obj instanceof Protobuf.Type ||
47 obj instanceof Protobuf.Enum);
48}
49function isNamespaceBase(obj) {
50 return obj instanceof Protobuf.Namespace || obj instanceof Protobuf.Root;
51}
52function getAllHandledReflectionObjects(obj, parentName) {
53 const objName = joinName(parentName, obj.name);
54 if (isHandledReflectionObject(obj)) {
55 return [[objName, obj]];
56 }
57 else {
58 if (isNamespaceBase(obj) && typeof obj.nested !== 'undefined') {
59 return Object.keys(obj.nested)
60 .map(name => {
61 return getAllHandledReflectionObjects(obj.nested[name], objName);
62 })
63 .reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
64 }
65 }
66 return [];
67}
68function createDeserializer(cls, options) {
69 return function deserialize(argBuf) {
70 return cls.toObject(cls.decode(argBuf), options);
71 };
72}
73function createSerializer(cls) {
74 return function serialize(arg) {
75 if (Array.isArray(arg)) {
76 throw new Error(`Failed to serialize message: expected object with ${cls.name} structure, got array instead`);
77 }
78 const message = cls.fromObject(arg);
79 return cls.encode(message).finish();
80 };
81}
82function createMethodDefinition(method, serviceName, options, fileDescriptors) {
83 /* This is only ever called after the corresponding root.resolveAll(), so we
84 * can assume that the resolved request and response types are non-null */
85 const requestType = method.resolvedRequestType;
86 const responseType = method.resolvedResponseType;
87 return {
88 path: '/' + serviceName + '/' + method.name,
89 requestStream: !!method.requestStream,
90 responseStream: !!method.responseStream,
91 requestSerialize: createSerializer(requestType),
92 requestDeserialize: createDeserializer(requestType, options),
93 responseSerialize: createSerializer(responseType),
94 responseDeserialize: createDeserializer(responseType, options),
95 // TODO(murgatroid99): Find a better way to handle this
96 originalName: camelCase(method.name),
97 requestType: createMessageDefinition(requestType, fileDescriptors),
98 responseType: createMessageDefinition(responseType, fileDescriptors),
99 };
100}
101function createServiceDefinition(service, name, options, fileDescriptors) {
102 const def = {};
103 for (const method of service.methodsArray) {
104 def[method.name] = createMethodDefinition(method, name, options, fileDescriptors);
105 }
106 return def;
107}
108function createMessageDefinition(message, fileDescriptors) {
109 const messageDescriptor = message.toDescriptor('proto3');
110 return {
111 format: 'Protocol Buffer 3 DescriptorProto',
112 type: messageDescriptor.$type.toObject(messageDescriptor, descriptorOptions),
113 fileDescriptorProtos: fileDescriptors,
114 };
115}
116function createEnumDefinition(enumType, fileDescriptors) {
117 const enumDescriptor = enumType.toDescriptor('proto3');
118 return {
119 format: 'Protocol Buffer 3 EnumDescriptorProto',
120 type: enumDescriptor.$type.toObject(enumDescriptor, descriptorOptions),
121 fileDescriptorProtos: fileDescriptors,
122 };
123}
124/**
125 * function createDefinition(obj: Protobuf.Service, name: string, options:
126 * Options): ServiceDefinition; function createDefinition(obj: Protobuf.Type,
127 * name: string, options: Options): MessageTypeDefinition; function
128 * createDefinition(obj: Protobuf.Enum, name: string, options: Options):
129 * EnumTypeDefinition;
130 */
131function createDefinition(obj, name, options, fileDescriptors) {
132 if (obj instanceof Protobuf.Service) {
133 return createServiceDefinition(obj, name, options, fileDescriptors);
134 }
135 else if (obj instanceof Protobuf.Type) {
136 return createMessageDefinition(obj, fileDescriptors);
137 }
138 else if (obj instanceof Protobuf.Enum) {
139 return createEnumDefinition(obj, fileDescriptors);
140 }
141 else {
142 throw new Error('Type mismatch in reflection object handling');
143 }
144}
145function createPackageDefinition(root, options) {
146 const def = {};
147 root.resolveAll();
148 const descriptorList = root.toDescriptor('proto3').file;
149 const bufferList = descriptorList.map(value => Buffer.from(descriptor.FileDescriptorProto.encode(value).finish()));
150 for (const [name, obj] of getAllHandledReflectionObjects(root, '')) {
151 def[name] = createDefinition(obj, name, options, bufferList);
152 }
153 return def;
154}
155function createPackageDefinitionFromDescriptorSet(decodedDescriptorSet, options) {
156 options = options || {};
157 const root = Protobuf.Root.fromDescriptor(decodedDescriptorSet);
158 root.resolveAll();
159 return createPackageDefinition(root, options);
160}
161/**
162 * Load a .proto file with the specified options.
163 * @param filename One or multiple file paths to load. Can be an absolute path
164 * or relative to an include path.
165 * @param options.keepCase Preserve field names. The default is to change them
166 * to camel case.
167 * @param options.longs The type that should be used to represent `long` values.
168 * Valid options are `Number` and `String`. Defaults to a `Long` object type
169 * from a library.
170 * @param options.enums The type that should be used to represent `enum` values.
171 * The only valid option is `String`. Defaults to the numeric value.
172 * @param options.bytes The type that should be used to represent `bytes`
173 * values. Valid options are `Array` and `String`. The default is to use
174 * `Buffer`.
175 * @param options.defaults Set default values on output objects. Defaults to
176 * `false`.
177 * @param options.arrays Set empty arrays for missing array values even if
178 * `defaults` is `false`. Defaults to `false`.
179 * @param options.objects Set empty objects for missing object values even if
180 * `defaults` is `false`. Defaults to `false`.
181 * @param options.oneofs Set virtual oneof properties to the present field's
182 * name
183 * @param options.json Represent Infinity and NaN as strings in float fields,
184 * and automatically decode google.protobuf.Any values.
185 * @param options.includeDirs Paths to search for imported `.proto` files.
186 */
187function load(filename, options) {
188 return util_1.loadProtosWithOptions(filename, options).then(loadedRoot => {
189 return createPackageDefinition(loadedRoot, options);
190 });
191}
192exports.load = load;
193function loadSync(filename, options) {
194 const loadedRoot = util_1.loadProtosWithOptionsSync(filename, options);
195 return createPackageDefinition(loadedRoot, options);
196}
197exports.loadSync = loadSync;
198function fromJSON(json, options) {
199 options = options || {};
200 const loadedRoot = Protobuf.Root.fromJSON(json);
201 loadedRoot.resolveAll();
202 return createPackageDefinition(loadedRoot, options);
203}
204exports.fromJSON = fromJSON;
205function loadFileDescriptorSetFromBuffer(descriptorSet, options) {
206 const decodedDescriptorSet = descriptor.FileDescriptorSet.decode(descriptorSet);
207 return createPackageDefinitionFromDescriptorSet(decodedDescriptorSet, options);
208}
209exports.loadFileDescriptorSetFromBuffer = loadFileDescriptorSetFromBuffer;
210function loadFileDescriptorSetFromObject(descriptorSet, options) {
211 const decodedDescriptorSet = descriptor.FileDescriptorSet.fromObject(descriptorSet);
212 return createPackageDefinitionFromDescriptorSet(decodedDescriptorSet, options);
213}
214exports.loadFileDescriptorSetFromObject = loadFileDescriptorSetFromObject;
215util_1.addCommonProtos();
216//# sourceMappingURL=index.js.map
\No newline at end of file