1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var util_1 = require("../util");
|
4 | var descriptor_pb_1 = require("google-protobuf/google/protobuf/descriptor_pb");
|
5 | var FieldTypes_1 = require("./FieldTypes");
|
6 | var Printer_1 = require("../Printer");
|
7 | var enum_1 = require("./enum");
|
8 | var oneof_1 = require("./oneof");
|
9 | var extensions_1 = require("./extensions");
|
10 | var JSType = descriptor_pb_1.FieldOptions.JSType;
|
11 | function hasFieldPresence(field, fileDescriptor) {
|
12 | if (field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED) {
|
13 | return false;
|
14 | }
|
15 | if (field.hasOneofIndex()) {
|
16 | return true;
|
17 | }
|
18 | if (field.getType() === FieldTypes_1.MESSAGE_TYPE) {
|
19 | return true;
|
20 | }
|
21 | if (util_1.isProto2(fileDescriptor)) {
|
22 | return true;
|
23 | }
|
24 | if (field.getProto3Optional()) {
|
25 | return true;
|
26 | }
|
27 | return false;
|
28 | }
|
29 | function jsGetterName(name) {
|
30 | return name === "Extension" || name === "JsPbMessageId" ? name + "$" : name;
|
31 | }
|
32 | function printMessage(fileName, exportMap, messageDescriptor, indentLevel, fileDescriptor) {
|
33 | var messageName = messageDescriptor.getName();
|
34 | var messageOptions = messageDescriptor.getOptions();
|
35 | if (messageOptions !== undefined && messageOptions.getMapEntry()) {
|
36 | return "";
|
37 | }
|
38 | var objectTypeName = "AsObject";
|
39 | var toObjectType = new Printer_1.Printer(indentLevel + 1);
|
40 | toObjectType.printLn("export type " + objectTypeName + " = {");
|
41 | var printer = new Printer_1.Printer(indentLevel);
|
42 | printer.printEmptyLn();
|
43 | printer.printLn("export class " + messageName + " extends jspb.Message {");
|
44 | var oneOfGroups = [];
|
45 | var syntheticOneOfGroups = [];
|
46 | messageDescriptor.getFieldList().forEach(function (field) {
|
47 | if (field.hasOneofIndex()) {
|
48 | var oneOfIndex = field.getOneofIndex();
|
49 | if (oneOfIndex === undefined) {
|
50 | util_1.throwError("Missing one_of index");
|
51 | }
|
52 | else if (field.getProto3Optional()) {
|
53 | syntheticOneOfGroups[oneOfIndex] = true;
|
54 | }
|
55 | else {
|
56 | var existing = oneOfGroups[oneOfIndex];
|
57 | if (existing === undefined) {
|
58 | existing = [];
|
59 | oneOfGroups[oneOfIndex] = existing;
|
60 | }
|
61 | existing.push(field);
|
62 | }
|
63 | }
|
64 | var fieldName = field.getName() || util_1.throwError("Missing field name");
|
65 | var snakeCaseName = util_1.stripPrefix(fieldName.toLowerCase(), "_");
|
66 | var camelCaseName = util_1.snakeToCamel(snakeCaseName);
|
67 | var withUppercase = util_1.uppercaseFirst(camelCaseName);
|
68 | var type = field.getType() || util_1.throwError("Missing field type");
|
69 | var exportType;
|
70 | if (type === FieldTypes_1.MESSAGE_TYPE) {
|
71 | var fieldTypeName = field.getTypeName() || util_1.throwError("Missing field type name for message field: " + fieldName);
|
72 | var fullTypeName = fieldTypeName.slice(1);
|
73 | var fieldMessageType = exportMap.getMessage(fullTypeName);
|
74 | if (fieldMessageType === undefined) {
|
75 | throw new Error("No message export for: " + fullTypeName);
|
76 | }
|
77 | if (fieldMessageType.messageOptions !== undefined && fieldMessageType.messageOptions.getMapEntry()) {
|
78 | var keyTuple = fieldMessageType.mapFieldOptions.key;
|
79 | var keyType = keyTuple[0];
|
80 | var keyTypeName = FieldTypes_1.getFieldType(keyType, keyTuple[1], fileName, exportMap);
|
81 | var valueTuple = fieldMessageType.mapFieldOptions.value;
|
82 | var valueType = valueTuple[0];
|
83 | var valueTypeName = FieldTypes_1.getFieldType(valueType, valueTuple[1], fileName, exportMap);
|
84 | if (valueType === FieldTypes_1.BYTES_TYPE) {
|
85 | valueTypeName = "Uint8Array | string";
|
86 | }
|
87 | if (valueType === FieldTypes_1.ENUM_TYPE) {
|
88 | valueTypeName = valueTypeName + "[keyof " + valueTypeName + "]";
|
89 | }
|
90 | printer.printIndentedLn("get" + withUppercase + "Map(): jspb.Map<" + keyTypeName + ", " + valueTypeName + ">;");
|
91 | printer.printIndentedLn("clear" + withUppercase + "Map(): void;");
|
92 | toObjectType.printIndentedLn(camelCaseName + "Map: Array<[" + keyTypeName + (keyType === FieldTypes_1.MESSAGE_TYPE ? ".AsObject" : "") + ", " + valueTypeName + (valueType === FieldTypes_1.MESSAGE_TYPE ? ".AsObject" : "") + "]>,");
|
93 | return;
|
94 | }
|
95 | var withinNamespace = util_1.withinNamespaceFromExportEntry(fullTypeName, fieldMessageType);
|
96 | if (fieldMessageType.fileName === fileName) {
|
97 | exportType = withinNamespace;
|
98 | }
|
99 | else {
|
100 | exportType = util_1.filePathToPseudoNamespace(fieldMessageType.fileName) + "." + withinNamespace;
|
101 | }
|
102 | }
|
103 | else if (type === FieldTypes_1.ENUM_TYPE) {
|
104 | var fieldTypeName = field.getTypeName() || util_1.throwError("Missing field type name for message field: " + fieldName);
|
105 | var fullTypeName = fieldTypeName.slice(1);
|
106 | var fieldEnumType = exportMap.getEnum(fullTypeName);
|
107 | if (fieldEnumType === undefined) {
|
108 | throw new Error("No enum export for: " + fullTypeName);
|
109 | }
|
110 | var withinNamespace = util_1.withinNamespaceFromExportEntry(fullTypeName, fieldEnumType);
|
111 | if (fieldEnumType.fileName === fileName) {
|
112 | exportType = withinNamespace;
|
113 | }
|
114 | else {
|
115 | exportType = util_1.filePathToPseudoNamespace(fieldEnumType.fileName) + "." + withinNamespace;
|
116 | }
|
117 | exportType = exportType + "Map[keyof " + exportType + "Map]";
|
118 | }
|
119 | else {
|
120 | var fieldOptions = field.getOptions();
|
121 | if (fieldOptions && fieldOptions.hasJstype()) {
|
122 | switch (fieldOptions.getJstype()) {
|
123 | case JSType.JS_NUMBER:
|
124 | exportType = "number";
|
125 | break;
|
126 | case JSType.JS_STRING:
|
127 | exportType = "string";
|
128 | break;
|
129 | default:
|
130 | exportType = FieldTypes_1.getTypeName(type);
|
131 | }
|
132 | }
|
133 | else {
|
134 | exportType = FieldTypes_1.getTypeName(type);
|
135 | }
|
136 | }
|
137 | var hasClearMethod = false;
|
138 | function printClearIfNotPresent() {
|
139 | if (!hasClearMethod) {
|
140 | hasClearMethod = true;
|
141 | printer.printIndentedLn("clear" + jsGetterName(withUppercase) + (field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED ? "List" : "") + "(): void;");
|
142 | }
|
143 | }
|
144 | if (hasFieldPresence(field, fileDescriptor)) {
|
145 | printer.printIndentedLn("has" + jsGetterName(withUppercase) + "(): boolean;");
|
146 | printClearIfNotPresent();
|
147 | }
|
148 | function printRepeatedAddMethod(valueType) {
|
149 | var optionalValue = field.getType() === FieldTypes_1.MESSAGE_TYPE;
|
150 | printer.printIndentedLn("add" + withUppercase + "(value" + (optionalValue ? "?" : "") + ": " + valueType + ", index?: number): " + valueType + ";");
|
151 | }
|
152 | if (field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED) {
|
153 | printClearIfNotPresent();
|
154 | if (type === FieldTypes_1.BYTES_TYPE) {
|
155 | toObjectType.printIndentedLn(camelCaseName + "List: Array<Uint8Array | string>,");
|
156 | printer.printIndentedLn("get" + withUppercase + "List(): Array<Uint8Array | string>;");
|
157 | printer.printIndentedLn("get" + withUppercase + "List_asU8(): Array<Uint8Array>;");
|
158 | printer.printIndentedLn("get" + withUppercase + "List_asB64(): Array<string>;");
|
159 | printer.printIndentedLn("set" + withUppercase + "List(value: Array<Uint8Array | string>): void;");
|
160 | printRepeatedAddMethod("Uint8Array | string");
|
161 | }
|
162 | else {
|
163 | toObjectType.printIndentedLn(camelCaseName + "List: Array<" + exportType + (type === FieldTypes_1.MESSAGE_TYPE ? ".AsObject" : "") + ">,");
|
164 | printer.printIndentedLn("get" + withUppercase + "List(): Array<" + exportType + ">;");
|
165 | printer.printIndentedLn("set" + withUppercase + "List(value: Array<" + exportType + ">): void;");
|
166 | printRepeatedAddMethod(exportType);
|
167 | }
|
168 | }
|
169 | else {
|
170 | if (type === FieldTypes_1.BYTES_TYPE) {
|
171 | toObjectType.printIndentedLn(camelCaseName + ": Uint8Array | string,");
|
172 | printer.printIndentedLn("get" + jsGetterName(withUppercase) + "(): Uint8Array | string;");
|
173 | printer.printIndentedLn("get" + withUppercase + "_asU8(): Uint8Array;");
|
174 | printer.printIndentedLn("get" + withUppercase + "_asB64(): string;");
|
175 | printer.printIndentedLn("set" + jsGetterName(withUppercase) + "(value: Uint8Array | string): void;");
|
176 | }
|
177 | else {
|
178 | var fieldObjectType = exportType;
|
179 | var canBeUndefined = false;
|
180 | if (type === FieldTypes_1.MESSAGE_TYPE) {
|
181 | fieldObjectType += ".AsObject";
|
182 | if (!util_1.isProto2(fileDescriptor) || (field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_OPTIONAL)) {
|
183 | canBeUndefined = true;
|
184 | }
|
185 | }
|
186 | else {
|
187 | if (util_1.isProto2(fileDescriptor)) {
|
188 | canBeUndefined = true;
|
189 | }
|
190 | }
|
191 | var fieldObjectName = util_1.normaliseFieldObjectName(camelCaseName);
|
192 | toObjectType.printIndentedLn("" + fieldObjectName + (canBeUndefined ? "?" : "") + ": " + fieldObjectType + ",");
|
193 | printer.printIndentedLn("get" + jsGetterName(withUppercase) + "(): " + exportType + (canBeUndefined ? " | undefined" : "") + ";");
|
194 | printer.printIndentedLn("set" + jsGetterName(withUppercase) + "(value" + (type === FieldTypes_1.MESSAGE_TYPE ? "?" : "") + ": " + exportType + "): void;");
|
195 | }
|
196 | }
|
197 | printer.printEmptyLn();
|
198 | });
|
199 | toObjectType.printLn("}");
|
200 | messageDescriptor.getOneofDeclList().forEach(function (oneOfDecl, index) {
|
201 | var oneOfDeclName = oneOfDecl.getName() || util_1.throwError("Missing one_of name");
|
202 | if (!syntheticOneOfGroups[index]) {
|
203 | printer.printIndentedLn("get" + util_1.oneOfName(oneOfDeclName) + "Case(): " + messageName + "." + util_1.oneOfName(oneOfDeclName) + "Case;");
|
204 | }
|
205 | });
|
206 | printer.printIndentedLn("serializeBinary(): Uint8Array;");
|
207 | printer.printIndentedLn("toObject(includeInstance?: boolean): " + messageName + "." + objectTypeName + ";");
|
208 | printer.printIndentedLn("static toObject(includeInstance: boolean, msg: " + messageName + "): " + messageName + "." + objectTypeName + ";");
|
209 | printer.printIndentedLn("static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};");
|
210 | printer.printIndentedLn("static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};");
|
211 | printer.printIndentedLn("static serializeBinaryToWriter(message: " + messageName + ", writer: jspb.BinaryWriter): void;");
|
212 | printer.printIndentedLn("static deserializeBinary(bytes: Uint8Array): " + messageName + ";");
|
213 | printer.printIndentedLn("static deserializeBinaryFromReader(message: " + messageName + ", reader: jspb.BinaryReader): " + messageName + ";");
|
214 | printer.printLn("}");
|
215 | printer.printEmptyLn();
|
216 | printer.printLn("export namespace " + messageName + " {");
|
217 | printer.print(toObjectType.getOutput());
|
218 | messageDescriptor.getNestedTypeList().forEach(function (nested) {
|
219 | var msgOutput = printMessage(fileName, exportMap, nested, indentLevel + 1, fileDescriptor);
|
220 | if (msgOutput !== "") {
|
221 | printer.print(msgOutput);
|
222 | }
|
223 | });
|
224 | messageDescriptor.getEnumTypeList().forEach(function (enumType) {
|
225 | printer.print("" + enum_1.printEnum(enumType, indentLevel + 1));
|
226 | });
|
227 | messageDescriptor.getOneofDeclList().forEach(function (oneOfDecl, index) {
|
228 | if (!syntheticOneOfGroups[index]) {
|
229 | printer.print("" + oneof_1.printOneOfDecl(oneOfDecl, oneOfGroups[index] || [], indentLevel + 1));
|
230 | }
|
231 | });
|
232 | messageDescriptor.getExtensionList().forEach(function (extension) {
|
233 | printer.print(extensions_1.printExtension(fileName, exportMap, extension, indentLevel + 1));
|
234 | });
|
235 | printer.printLn("}");
|
236 | return printer.getOutput();
|
237 | }
|
238 | exports.printMessage = printMessage;
|
239 |
|
\ | No newline at end of file |