@bufbuild/protoplugin 2.0.0-alpha.1 → 2.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/cjs/create-es-plugin.d.ts +3 -3
  2. package/dist/cjs/create-es-plugin.js +6 -6
  3. package/dist/cjs/{ecmascript/file-preamble.js → file-preamble.js} +4 -1
  4. package/dist/cjs/{ecmascript/generated-file.d.ts → generated-file.d.ts} +3 -3
  5. package/dist/cjs/{ecmascript/generated-file.js → generated-file.js} +13 -14
  6. package/dist/cjs/index.d.ts +7 -0
  7. package/dist/cjs/index.js +5 -1
  8. package/dist/cjs/{ecmascript/jsdoc.js → jsdoc.js} +18 -6
  9. package/dist/cjs/{ecmascript/parameter.js → parameter.js} +2 -2
  10. package/dist/{esm/ecmascript → cjs}/printable.d.ts +2 -3
  11. package/dist/cjs/{ecmascript/schema.js → schema.js} +10 -2
  12. package/dist/cjs/source-code-info.d.ts +6 -1
  13. package/dist/cjs/source-code-info.js +74 -47
  14. package/dist/esm/create-es-plugin.d.ts +3 -3
  15. package/dist/esm/create-es-plugin.js +4 -4
  16. package/dist/esm/{ecmascript/file-preamble.js → file-preamble.js} +4 -1
  17. package/dist/esm/{ecmascript/generated-file.d.ts → generated-file.d.ts} +3 -3
  18. package/dist/esm/{ecmascript/generated-file.js → generated-file.js} +12 -13
  19. package/dist/esm/index.d.ts +7 -0
  20. package/dist/esm/index.js +2 -0
  21. package/dist/esm/{ecmascript/jsdoc.js → jsdoc.js} +18 -6
  22. package/dist/esm/{ecmascript/parameter.js → parameter.js} +2 -2
  23. package/dist/{cjs/ecmascript → esm}/printable.d.ts +2 -3
  24. package/dist/esm/{ecmascript/schema.js → schema.js} +11 -3
  25. package/dist/esm/source-code-info.d.ts +6 -1
  26. package/dist/esm/source-code-info.js +73 -47
  27. package/dist/esm/{ecmascript/printable.js → target.js} +1 -1
  28. package/package.json +2 -13
  29. package/dist/cjs/ecmascript/index.d.ts +0 -7
  30. package/dist/cjs/ecmascript/index.js +0 -20
  31. package/dist/esm/ecmascript/index.d.ts +0 -7
  32. package/dist/esm/ecmascript/index.js +0 -15
  33. /package/dist/cjs/{ecmascript/file-preamble.d.ts → file-preamble.d.ts} +0 -0
  34. /package/dist/cjs/{ecmascript/import-path.d.ts → import-path.d.ts} +0 -0
  35. /package/dist/cjs/{ecmascript/import-path.js → import-path.js} +0 -0
  36. /package/dist/cjs/{ecmascript/import-symbol.d.ts → import-symbol.d.ts} +0 -0
  37. /package/dist/cjs/{ecmascript/import-symbol.js → import-symbol.js} +0 -0
  38. /package/dist/cjs/{ecmascript/jsdoc.d.ts → jsdoc.d.ts} +0 -0
  39. /package/dist/cjs/{ecmascript/names.d.ts → names.d.ts} +0 -0
  40. /package/dist/cjs/{ecmascript/names.js → names.js} +0 -0
  41. /package/dist/cjs/{ecmascript/parameter.d.ts → parameter.d.ts} +0 -0
  42. /package/dist/cjs/{ecmascript/printable.js → printable.js} +0 -0
  43. /package/dist/cjs/{ecmascript/runtime-imports.d.ts → runtime-imports.d.ts} +0 -0
  44. /package/dist/cjs/{ecmascript/runtime-imports.js → runtime-imports.js} +0 -0
  45. /package/dist/cjs/{ecmascript/safe-identifier.d.ts → safe-identifier.d.ts} +0 -0
  46. /package/dist/cjs/{ecmascript/safe-identifier.js → safe-identifier.js} +0 -0
  47. /package/dist/cjs/{ecmascript/schema.d.ts → schema.d.ts} +0 -0
  48. /package/dist/cjs/{ecmascript/target.d.ts → target.d.ts} +0 -0
  49. /package/dist/cjs/{ecmascript/target.js → target.js} +0 -0
  50. /package/dist/cjs/{ecmascript/transpile.d.ts → transpile.d.ts} +0 -0
  51. /package/dist/cjs/{ecmascript/transpile.js → transpile.js} +0 -0
  52. /package/dist/esm/{ecmascript/file-preamble.d.ts → file-preamble.d.ts} +0 -0
  53. /package/dist/esm/{ecmascript/import-path.d.ts → import-path.d.ts} +0 -0
  54. /package/dist/esm/{ecmascript/import-path.js → import-path.js} +0 -0
  55. /package/dist/esm/{ecmascript/import-symbol.d.ts → import-symbol.d.ts} +0 -0
  56. /package/dist/esm/{ecmascript/import-symbol.js → import-symbol.js} +0 -0
  57. /package/dist/esm/{ecmascript/jsdoc.d.ts → jsdoc.d.ts} +0 -0
  58. /package/dist/esm/{ecmascript/names.d.ts → names.d.ts} +0 -0
  59. /package/dist/esm/{ecmascript/names.js → names.js} +0 -0
  60. /package/dist/esm/{ecmascript/parameter.d.ts → parameter.d.ts} +0 -0
  61. /package/dist/esm/{ecmascript/target.js → printable.js} +0 -0
  62. /package/dist/esm/{ecmascript/runtime-imports.d.ts → runtime-imports.d.ts} +0 -0
  63. /package/dist/esm/{ecmascript/runtime-imports.js → runtime-imports.js} +0 -0
  64. /package/dist/esm/{ecmascript/safe-identifier.d.ts → safe-identifier.d.ts} +0 -0
  65. /package/dist/esm/{ecmascript/safe-identifier.js → safe-identifier.js} +0 -0
  66. /package/dist/esm/{ecmascript/schema.d.ts → schema.d.ts} +0 -0
  67. /package/dist/esm/{ecmascript/target.d.ts → target.d.ts} +0 -0
  68. /package/dist/esm/{ecmascript/transpile.d.ts → transpile.d.ts} +0 -0
  69. /package/dist/esm/{ecmascript/transpile.js → transpile.js} +0 -0
@@ -1,6 +1,6 @@
1
- import type { SupportedEdition } from "@bufbuild/protobuf";
2
- import type { Schema } from "./ecmascript/schema.js";
3
- import type { FileInfo } from "./ecmascript/generated-file.js";
1
+ import { type SupportedEdition } from "@bufbuild/protobuf";
2
+ import type { Schema } from "./schema.js";
3
+ import type { FileInfo } from "./generated-file.js";
4
4
  import type { Plugin } from "./plugin.js";
5
5
  interface PluginInit {
6
6
  /**
@@ -15,11 +15,11 @@
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.createEcmaScriptPlugin = void 0;
17
17
  const protobuf_1 = require("@bufbuild/protobuf");
18
- const reflect_1 = require("@bufbuild/protobuf/reflect");
18
+ const protobuf_2 = require("@bufbuild/protobuf");
19
19
  const wkt_1 = require("@bufbuild/protobuf/wkt");
20
- const schema_js_1 = require("./ecmascript/schema.js");
21
- const transpile_js_1 = require("./ecmascript/transpile.js");
22
- const parameter_js_1 = require("./ecmascript/parameter.js");
20
+ const schema_js_1 = require("./schema.js");
21
+ const transpile_js_1 = require("./transpile.js");
22
+ const parameter_js_1 = require("./parameter.js");
23
23
  /**
24
24
  * Create a new code generator plugin for ECMAScript.
25
25
  * The plugin can generate JavaScript, TypeScript, or TypeScript declaration
@@ -33,8 +33,8 @@ function createEcmaScriptPlugin(init) {
33
33
  version: init.version,
34
34
  run(req) {
35
35
  var _a, _b, _c;
36
- const minimumEdition = (_a = init.minimumEdition) !== null && _a !== void 0 ? _a : reflect_1.minimumEdition;
37
- const maximumEdition = (_b = init.maximumEdition) !== null && _b !== void 0 ? _b : reflect_1.maximumEdition;
36
+ const minimumEdition = (_a = init.minimumEdition) !== null && _a !== void 0 ? _a : protobuf_2.minimumEdition;
37
+ const maximumEdition = (_b = init.maximumEdition) !== null && _b !== void 0 ? _b : protobuf_2.maximumEdition;
38
38
  const parameter = (0, parameter_js_1.parseParameter)(req.parameter, init.parseOption);
39
39
  const schema = (0, schema_js_1.createSchema)(req, parameter, init.name, init.version, minimumEdition, maximumEdition);
40
40
  const targetTs = schema.targets.includes("ts");
@@ -15,7 +15,7 @@
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.makeFilePreamble = void 0;
17
17
  const wkt_1 = require("@bufbuild/protobuf/wkt");
18
- const source_code_info_js_1 = require("../source-code-info.js");
18
+ const source_code_info_js_1 = require("./source-code-info.js");
19
19
  function makeFilePreamble(file, pluginName, pluginVersion, parameter, tsNoCheck) {
20
20
  const builder = [];
21
21
  const trimSuffix = (str, suffix) => str.endsWith(suffix) ? str.substring(0, str.length - suffix.length) : str;
@@ -64,6 +64,9 @@ function makeFilePreamble(file, pluginName, pluginVersion, parameter, tsNoCheck)
64
64
  break;
65
65
  }
66
66
  }
67
+ for (const o of (0, source_code_info_js_1.getFeatureOptionStrings)(file)) {
68
+ builder.push(`// option ${o};\n`);
69
+ }
67
70
  builder.push("/* eslint-disable */\n");
68
71
  if (tsNoCheck) {
69
72
  builder.push("// @ts-nocheck\n");
@@ -1,4 +1,4 @@
1
- import type { AnyDesc, DescEnum, DescExtension, DescFile, DescMessage, DescService } from "@bufbuild/protobuf";
1
+ import { type AnyDesc, type DescEnum, type DescExtension, type DescFile, type DescMessage, type DescService } from "@bufbuild/protobuf";
2
2
  import type { ImportSymbol } from "./import-symbol.js";
3
3
  import type { Printable } from "./printable.js";
4
4
  import type { RuntimeImports } from "./runtime-imports.js";
@@ -63,7 +63,7 @@ export interface GeneratedFile {
63
63
  * Create a printable export statement. For example:
64
64
  *
65
65
  * ```ts
66
- * f.print(f.exportDecl("abstract class", "MyClass"), " {}")
66
+ * f.print(f.export("abstract class", "MyClass"), " {}")
67
67
  * ```
68
68
  *
69
69
  * Will generate as:
@@ -75,7 +75,7 @@ export interface GeneratedFile {
75
75
  * statement. If the plugin option `js_import_style=legacy_commonjs` is set,
76
76
  * exports will automatically be generated for CommonJS.
77
77
  */
78
- exportDecl(declaration: string, name: string): Printable;
78
+ export(declaration: string, name: string): Printable;
79
79
  /**
80
80
  * Import a message or enumeration generated by protoc-gen-es.
81
81
  */
@@ -15,7 +15,6 @@
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.createGeneratedFile = void 0;
17
17
  const protobuf_1 = require("@bufbuild/protobuf");
18
- const reflect_1 = require("@bufbuild/protobuf/reflect");
19
18
  const import_symbol_js_1 = require("./import-symbol.js");
20
19
  const import_path_js_1 = require("./import-path.js");
21
20
  const jsdoc_js_1 = require("./jsdoc.js");
@@ -48,7 +47,7 @@ function createGeneratedFile(name, importPath, jsImportStyle, rewriteImport, res
48
47
  }, printables);
49
48
  el.push("\n");
50
49
  },
51
- exportDecl(declaration, name) {
50
+ export(declaration, name) {
52
51
  return {
53
52
  kind: "es_export_stmt",
54
53
  name,
@@ -231,25 +230,25 @@ function printableToEl(opt, printables) {
231
230
  el.push(escapeString(p.value));
232
231
  break;
233
232
  case "es_proto_int64":
234
- switch (p.longType) {
235
- case reflect_1.LongType.STRING:
236
- el.push(escapeString(p.value.toString()));
237
- break;
238
- case reflect_1.LongType.BIGINT:
239
- if (p.value == protobuf_1.protoInt64.zero) {
240
- // Loose comparison will match between 0n and 0.
241
- el.push(opt.runtime.protoInt64, ".zero");
242
- break;
243
- }
233
+ if (p.longAsString) {
234
+ el.push(escapeString(p.value.toString()));
235
+ }
236
+ else {
237
+ if (p.value == protobuf_1.protoInt64.zero) {
238
+ // Loose comparison will match between 0n and 0.
239
+ el.push(opt.runtime.protoInt64, ".zero");
240
+ }
241
+ else {
244
242
  switch (p.type) {
245
- case reflect_1.ScalarType.UINT64:
246
- case reflect_1.ScalarType.FIXED64:
243
+ case protobuf_1.ScalarType.UINT64:
244
+ case protobuf_1.ScalarType.FIXED64:
247
245
  el.push(opt.runtime.protoInt64, ".uParse(", escapeString(p.value.toString()), ")");
248
246
  break;
249
247
  default:
250
248
  el.push(opt.runtime.protoInt64, ".parse(", escapeString(p.value.toString()), ")");
251
249
  break;
252
250
  }
251
+ }
253
252
  }
254
253
  break;
255
254
  default:
@@ -2,3 +2,10 @@ export type { Plugin } from "./plugin.js";
2
2
  export { runNodeJs } from "./run-node.js";
3
3
  export { createEcmaScriptPlugin } from "./create-es-plugin.js";
4
4
  export { getComments, getDeclarationString, getPackageComments, getSyntaxComments, } from "./source-code-info.js";
5
+ export type { Target } from "./target.js";
6
+ export type { Schema } from "./schema.js";
7
+ export type { GeneratedFile, FileInfo } from "./generated-file.js";
8
+ export type { ImportSymbol } from "./import-symbol.js";
9
+ export { createImportSymbol } from "./import-symbol.js";
10
+ export type { Printable } from "./printable.js";
11
+ export { safeIdentifier } from "./safe-identifier.js";
package/dist/cjs/index.js CHANGED
@@ -13,7 +13,7 @@
13
13
  // See the License for the specific language governing permissions and
14
14
  // limitations under the License.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.getSyntaxComments = exports.getPackageComments = exports.getDeclarationString = exports.getComments = exports.createEcmaScriptPlugin = exports.runNodeJs = void 0;
16
+ exports.safeIdentifier = exports.createImportSymbol = exports.getSyntaxComments = exports.getPackageComments = exports.getDeclarationString = exports.getComments = exports.createEcmaScriptPlugin = exports.runNodeJs = void 0;
17
17
  var run_node_js_1 = require("./run-node.js");
18
18
  Object.defineProperty(exports, "runNodeJs", { enumerable: true, get: function () { return run_node_js_1.runNodeJs; } });
19
19
  var create_es_plugin_js_1 = require("./create-es-plugin.js");
@@ -23,3 +23,7 @@ Object.defineProperty(exports, "getComments", { enumerable: true, get: function
23
23
  Object.defineProperty(exports, "getDeclarationString", { enumerable: true, get: function () { return source_code_info_js_1.getDeclarationString; } });
24
24
  Object.defineProperty(exports, "getPackageComments", { enumerable: true, get: function () { return source_code_info_js_1.getPackageComments; } });
25
25
  Object.defineProperty(exports, "getSyntaxComments", { enumerable: true, get: function () { return source_code_info_js_1.getSyntaxComments; } });
26
+ var import_symbol_js_1 = require("./import-symbol.js");
27
+ Object.defineProperty(exports, "createImportSymbol", { enumerable: true, get: function () { return import_symbol_js_1.createImportSymbol; } });
28
+ var safe_identifier_js_1 = require("./safe-identifier.js");
29
+ Object.defineProperty(exports, "safeIdentifier", { enumerable: true, get: function () { return safe_identifier_js_1.safeIdentifier; } });
@@ -14,7 +14,8 @@
14
14
  // limitations under the License.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.formatJsDocBlock = exports.createJsDocTextFromDesc = void 0;
17
- const source_code_info_js_1 = require("../source-code-info.js");
17
+ const source_code_info_js_1 = require("./source-code-info.js");
18
+ const reflect_1 = require("@bufbuild/protobuf/reflect");
18
19
  function createJsDocTextFromDesc(desc) {
19
20
  const comments = (0, source_code_info_js_1.getComments)(desc);
20
21
  let text = "";
@@ -50,18 +51,29 @@ function createJsDocTextFromDesc(desc) {
50
51
  case "extension":
51
52
  text += `@generated from extension: ${(0, source_code_info_js_1.getDeclarationString)(desc)};`;
52
53
  break;
54
+ case "message":
55
+ case "enum": {
56
+ text += `@generated from ${desc.toString()}`;
57
+ const featureOptions = (0, source_code_info_js_1.getFeatureOptionStrings)(desc);
58
+ if (featureOptions.length > 0) {
59
+ text += `\n@generated with ${featureOptions.length > 1 ? "options" : "option"} ${featureOptions.join(", ")}`;
60
+ }
61
+ break;
62
+ }
53
63
  default:
54
64
  text += `@generated from ${desc.toString()}`;
55
65
  break;
56
66
  }
57
- let deprecated = desc.deprecated;
67
+ let deprecated;
58
68
  switch (desc.kind) {
59
- case "enum":
60
- case "message":
61
- case "service":
62
- deprecated = deprecated || desc.file.deprecated;
69
+ case "field":
70
+ case "enum_value":
71
+ case "rpc":
72
+ deprecated = desc.deprecated;
63
73
  break;
64
74
  default:
75
+ deprecated =
76
+ desc.deprecated || (0, reflect_1.parentTypes)(desc).some((d) => d.deprecated);
65
77
  break;
66
78
  }
67
79
  if (deprecated) {
@@ -14,14 +14,14 @@
14
14
  // limitations under the License.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.parseParameter = void 0;
17
- const error_js_1 = require("../error.js");
17
+ const error_js_1 = require("./error.js");
18
18
  function parseParameter(parameter, parseExtraOption) {
19
19
  let targets = ["js", "dts"];
20
20
  let tsNocheck = false;
21
21
  let bootstrapWkt = false;
22
22
  let keepEmptyFiles = false;
23
23
  const rewriteImports = [];
24
- let importExtension = ".js";
24
+ let importExtension = "";
25
25
  let jsImportStyle = "module";
26
26
  const rawParameters = [];
27
27
  for (const { key, value, raw } of splitParameter(parameter)) {
@@ -1,5 +1,4 @@
1
- import type { DescEnum, DescExtension, DescFile, DescMessage, DescService } from "@bufbuild/protobuf";
2
- import { ScalarType, LongType } from "@bufbuild/protobuf/reflect";
1
+ import type { DescEnum, DescExtension, DescFile, DescMessage, DescService, ScalarType } from "@bufbuild/protobuf";
3
2
  import type { ImportSymbol } from "./import-symbol.js";
4
3
  /**
5
4
  * All types that can be passed to GeneratedFile.print()
@@ -13,7 +12,7 @@ export type ExportStatement = {
13
12
  export type LiteralProtoInt64 = {
14
13
  readonly kind: "es_proto_int64";
15
14
  type: ScalarType.INT64 | ScalarType.SINT64 | ScalarType.SFIXED64 | ScalarType.UINT64 | ScalarType.FIXED64;
16
- longType: LongType;
15
+ longAsString: boolean;
17
16
  value: bigint | string;
18
17
  };
19
18
  export type LiteralString = {
@@ -92,8 +92,16 @@ function getFilesToGenerate(request, minimumEdition, maximumEdition) {
92
92
  }
93
93
  }
94
94
  }
95
- const registry = (0, reflect_1.createFileRegistry)((0, protobuf_1.create)(wkt_1.FileDescriptorSetDesc, {
96
- file: request.protoFile,
95
+ // Our goal is to provide options with source retention to plugin authors.
96
+ // CodeGeneratorRequest.proto_file elides options with source retention for
97
+ // files to generate. For these files, we take the file from source_file_descriptors,
98
+ // which does include options with source retention.
99
+ const allProtoWithSourceOptions = request.protoFile.map((protoFile) => {
100
+ const sourceFile = request.sourceFileDescriptors.find((s) => s.name == protoFile.name);
101
+ return sourceFile !== null && sourceFile !== void 0 ? sourceFile : protoFile;
102
+ });
103
+ const registry = (0, protobuf_1.createFileRegistry)((0, protobuf_1.create)(wkt_1.FileDescriptorSetDesc, {
104
+ file: allProtoWithSourceOptions,
97
105
  }));
98
106
  const allFiles = [];
99
107
  const filesToGenerate = [];
@@ -1,4 +1,4 @@
1
- import type { DescField, DescEnumValue, DescExtension, DescComments, AnyDesc, DescFile } from "@bufbuild/protobuf";
1
+ import { type AnyDesc, type DescComments, type DescEnumValue, type DescExtension, type DescField, type DescFile } from "@bufbuild/protobuf";
2
2
  /**
3
3
  * Get comments on the package element in the protobuf source.
4
4
  */
@@ -11,6 +11,11 @@ export declare function getSyntaxComments(desc: DescFile): DescComments;
11
11
  * Get comments on the element in the protobuf source.
12
12
  */
13
13
  export declare function getComments(desc: Exclude<AnyDesc, DescFile>): DescComments;
14
+ /**
15
+ * Get feature options set on the element in the protobuf source. This returns
16
+ * compact (e.g. fields) or regular options (e.g. files) as an array of strings.
17
+ */
18
+ export declare function getFeatureOptionStrings(desc: AnyDesc): string[];
14
19
  /**
15
20
  * Return a string that matches the definition of a field in the protobuf
16
21
  * source. Does not take custom options into account.
@@ -13,7 +13,7 @@
13
13
  // See the License for the specific language governing permissions and
14
14
  // limitations under the License.
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.getDeclarationString = exports.getComments = exports.getSyntaxComments = exports.getPackageComments = void 0;
16
+ exports.getDeclarationString = exports.getFeatureOptionStrings = exports.getComments = exports.getSyntaxComments = exports.getPackageComments = void 0;
17
17
  const protobuf_1 = require("@bufbuild/protobuf");
18
18
  const reflect_1 = require("@bufbuild/protobuf/reflect");
19
19
  const wkt_1 = require("@bufbuild/protobuf/wkt");
@@ -22,7 +22,7 @@ const wkt_1 = require("@bufbuild/protobuf/wkt");
22
22
  */
23
23
  function getPackageComments(desc) {
24
24
  return findComments(desc.proto.sourceCodeInfo, [
25
- FieldNumber.FileDescriptorProto_Package,
25
+ wkt_1.FileDescriptorProtoDesc.field.package.number,
26
26
  ]);
27
27
  }
28
28
  exports.getPackageComments = getPackageComments;
@@ -31,7 +31,7 @@ exports.getPackageComments = getPackageComments;
31
31
  */
32
32
  function getSyntaxComments(desc) {
33
33
  return findComments(desc.proto.sourceCodeInfo, [
34
- FieldNumber.FileDescriptorProto_Syntax,
34
+ wkt_1.FileDescriptorProtoDesc.field.syntax.number,
35
35
  ]);
36
36
  }
37
37
  exports.getSyntaxComments = getSyntaxComments;
@@ -46,11 +46,11 @@ function getComments(desc) {
46
46
  path = desc.parent
47
47
  ? [
48
48
  ...getComments(desc.parent).sourcePath,
49
- FieldNumber.DescriptorProto_EnumType,
49
+ wkt_1.DescriptorProtoDesc.field.enumType.number,
50
50
  desc.parent.proto.enumType.indexOf(desc.proto),
51
51
  ]
52
52
  : [
53
- FieldNumber.FileDescriptorProto_EnumType,
53
+ wkt_1.FileDescriptorProtoDesc.field.enumType.number,
54
54
  desc.file.proto.enumType.indexOf(desc.proto),
55
55
  ];
56
56
  file = desc.file;
@@ -58,7 +58,7 @@ function getComments(desc) {
58
58
  case "oneof":
59
59
  path = [
60
60
  ...getComments(desc.parent).sourcePath,
61
- FieldNumber.DescriptorProto_OneofDecl,
61
+ wkt_1.DescriptorProtoDesc.field.oneofDecl.number,
62
62
  desc.parent.proto.oneofDecl.indexOf(desc.proto),
63
63
  ];
64
64
  file = desc.parent.file;
@@ -67,11 +67,11 @@ function getComments(desc) {
67
67
  path = desc.parent
68
68
  ? [
69
69
  ...getComments(desc.parent).sourcePath,
70
- FieldNumber.DescriptorProto_NestedType,
70
+ wkt_1.DescriptorProtoDesc.field.nestedType.number,
71
71
  desc.parent.proto.nestedType.indexOf(desc.proto),
72
72
  ]
73
73
  : [
74
- FieldNumber.FileDescriptorProto_MessageType,
74
+ wkt_1.FileDescriptorProtoDesc.field.messageType.number,
75
75
  desc.file.proto.messageType.indexOf(desc.proto),
76
76
  ];
77
77
  file = desc.file;
@@ -79,7 +79,7 @@ function getComments(desc) {
79
79
  case "enum_value":
80
80
  path = [
81
81
  ...getComments(desc.parent).sourcePath,
82
- FieldNumber.EnumDescriptorProto_Value,
82
+ wkt_1.EnumDescriptorProtoDesc.field.value.number,
83
83
  desc.parent.proto.value.indexOf(desc.proto),
84
84
  ];
85
85
  file = desc.parent.file;
@@ -87,7 +87,7 @@ function getComments(desc) {
87
87
  case "field":
88
88
  path = [
89
89
  ...getComments(desc.parent).sourcePath,
90
- FieldNumber.DescriptorProto_Field,
90
+ wkt_1.DescriptorProtoDesc.field.field.number,
91
91
  desc.parent.proto.field.indexOf(desc.proto),
92
92
  ];
93
93
  file = desc.parent.file;
@@ -96,18 +96,18 @@ function getComments(desc) {
96
96
  path = desc.parent
97
97
  ? [
98
98
  ...getComments(desc.parent).sourcePath,
99
- FieldNumber.DescriptorProto_Extension,
99
+ wkt_1.DescriptorProtoDesc.field.extension.number,
100
100
  desc.parent.proto.extension.indexOf(desc.proto),
101
101
  ]
102
102
  : [
103
- FieldNumber.FileDescriptorProto_Extension,
103
+ wkt_1.FileDescriptorProtoDesc.field.extension.number,
104
104
  desc.file.proto.extension.indexOf(desc.proto),
105
105
  ];
106
106
  file = desc.file;
107
107
  break;
108
108
  case "service":
109
109
  path = [
110
- FieldNumber.FileDescriptorProto_Service,
110
+ wkt_1.FileDescriptorProtoDesc.field.service.number,
111
111
  desc.file.proto.service.indexOf(desc.proto),
112
112
  ];
113
113
  file = desc.file;
@@ -115,7 +115,7 @@ function getComments(desc) {
115
115
  case "rpc":
116
116
  path = [
117
117
  ...getComments(desc.parent).sourcePath,
118
- FieldNumber.ServiceDescriptorProto_Method,
118
+ wkt_1.ServiceDescriptorProtoDesc.field.method.number,
119
119
  desc.parent.proto.method.indexOf(desc.proto),
120
120
  ];
121
121
  file = desc.parent.file;
@@ -124,6 +124,30 @@ function getComments(desc) {
124
124
  return findComments(file.proto.sourceCodeInfo, path);
125
125
  }
126
126
  exports.getComments = getComments;
127
+ /**
128
+ * Get feature options set on the element in the protobuf source. This returns
129
+ * compact (e.g. fields) or regular options (e.g. files) as an array of strings.
130
+ */
131
+ function getFeatureOptionStrings(desc) {
132
+ var _a, _b;
133
+ const strings = [];
134
+ const features = (_a = desc.proto.options) === null || _a === void 0 ? void 0 : _a.features;
135
+ if (features !== undefined) {
136
+ const r = (0, reflect_1.reflect)(wkt_1.FeatureSetDesc, features);
137
+ for (const f of r.fields) {
138
+ if (f.fieldKind != "enum" || !r.isSet(f)) {
139
+ continue;
140
+ }
141
+ const val = r.get(f);
142
+ const name = (_b = f.enum.values.find((v) => v.number == val)) === null || _b === void 0 ? void 0 : _b.name;
143
+ if (name !== undefined) {
144
+ strings.push(`features.${f.name} = ${name}`);
145
+ }
146
+ }
147
+ }
148
+ return strings;
149
+ }
150
+ exports.getFeatureOptionStrings = getFeatureOptionStrings;
127
151
  /**
128
152
  * Return a string that matches the definition of a field in the protobuf
129
153
  * source. Does not take custom options into account.
@@ -137,7 +161,6 @@ function getDeclarationString(desc) {
137
161
  }
138
162
  return str;
139
163
  }
140
- const file = desc.kind === "extension" ? desc.file : desc.parent.file;
141
164
  const parts = [];
142
165
  function typeName(f) {
143
166
  if (f.message) {
@@ -146,18 +169,16 @@ function getDeclarationString(desc) {
146
169
  if (f.enum) {
147
170
  return f.enum.typeName;
148
171
  }
149
- return reflect_1.ScalarType[f.scalar].toLowerCase();
172
+ return protobuf_1.ScalarType[f.scalar].toLowerCase();
150
173
  }
151
174
  switch (desc.fieldKind) {
152
175
  case "scalar":
153
176
  case "enum":
154
177
  case "message":
155
- if (file.edition === wkt_1.Edition.EDITION_PROTO2 &&
156
- (0, protobuf_1.isFieldSet)(wkt_1.FieldDescriptorProtoDesc, desc.proto, "label") &&
157
- desc.proto.label == wkt_1.FieldDescriptorProto_Label.REQUIRED) {
178
+ if (fieldHasRequiredKeyword(desc)) {
158
179
  parts.push("required");
159
180
  }
160
- if (desc.optional) {
181
+ if (fieldHasOptionalKeyword(desc)) {
161
182
  parts.push("optional");
162
183
  }
163
184
  parts.push(typeName(desc));
@@ -166,7 +187,7 @@ function getDeclarationString(desc) {
166
187
  parts.push("repeated", typeName(desc));
167
188
  break;
168
189
  case "map": {
169
- const k = reflect_1.ScalarType[desc.mapKey].toLowerCase();
190
+ const k = protobuf_1.ScalarType[desc.mapKey].toLowerCase();
170
191
  const v = typeName(desc);
171
192
  parts.push(`map<${k}, ${v}>`);
172
193
  break;
@@ -176,10 +197,10 @@ function getDeclarationString(desc) {
176
197
  const options = [];
177
198
  const protoOptions = desc.proto.options;
178
199
  if (protoOptions !== undefined &&
179
- (0, protobuf_1.isFieldSet)(wkt_1.FieldOptionsDesc, protoOptions, "packed")) {
200
+ (0, protobuf_1.isFieldSet)(protoOptions, wkt_1.FieldOptionsDesc.field.packed)) {
180
201
  options.push(`packed = ${protoOptions.packed.toString()}`);
181
202
  }
182
- if ((0, protobuf_1.isFieldSet)(wkt_1.FieldDescriptorProtoDesc, desc.proto, "defaultValue")) {
203
+ if ((0, protobuf_1.isFieldSet)(desc.proto, wkt_1.FieldDescriptorProtoDesc.field.defaultValue)) {
183
204
  let defaultValue = desc.proto.defaultValue;
184
205
  if (desc.proto.type == wkt_1.FieldDescriptorProto_Type.BYTES ||
185
206
  desc.proto.type == wkt_1.FieldDescriptorProto_Type.STRING) {
@@ -191,19 +212,45 @@ function getDeclarationString(desc) {
191
212
  options.push(`json_name = "${desc.jsonName}"`);
192
213
  }
193
214
  if (protoOptions !== undefined &&
194
- (0, protobuf_1.isFieldSet)(wkt_1.FieldOptionsDesc, protoOptions, "jstype")) {
215
+ (0, protobuf_1.isFieldSet)(protoOptions, wkt_1.FieldOptionsDesc.field.jstype)) {
195
216
  options.push(`jstype = ${wkt_1.FieldOptions_JSType[protoOptions.jstype]}`);
196
217
  }
197
218
  if (protoOptions !== undefined &&
198
- (0, protobuf_1.isFieldSet)(wkt_1.FieldOptionsDesc, protoOptions, "deprecated")) {
219
+ (0, protobuf_1.isFieldSet)(protoOptions, wkt_1.FieldOptionsDesc.field.deprecated)) {
199
220
  options.push(`deprecated = true`);
200
221
  }
222
+ options.push(...getFeatureOptionStrings(desc));
201
223
  if (options.length > 0) {
202
224
  parts.push("[" + options.join(", ") + "]");
203
225
  }
204
226
  return parts.join(" ");
205
227
  }
206
228
  exports.getDeclarationString = getDeclarationString;
229
+ /**
230
+ * Whether this field was declared with `required` in the protobuf source.
231
+ */
232
+ function fieldHasRequiredKeyword(field) {
233
+ const edition = (field.kind == "extension" ? field.file : field.parent.file)
234
+ .edition;
235
+ return (edition == wkt_1.Edition.EDITION_PROTO2 &&
236
+ field.proto.label == wkt_1.FieldDescriptorProto_Label.REQUIRED);
237
+ }
238
+ /**
239
+ * Whether this field was declared with `optional` in the protobuf source.
240
+ * Note that message fields are always optional. It is impossible to determine
241
+ * whether the keyword was used.
242
+ */
243
+ function fieldHasOptionalKeyword(field) {
244
+ const edition = (field.kind == "extension" ? field.file : field.parent.file)
245
+ .edition;
246
+ if (edition == wkt_1.Edition.EDITION_PROTO2) {
247
+ return (!field.oneof && field.proto.label == wkt_1.FieldDescriptorProto_Label.OPTIONAL);
248
+ }
249
+ if (edition == wkt_1.Edition.EDITION_PROTO3) {
250
+ return field.proto.proto3Optional;
251
+ }
252
+ return false;
253
+ }
207
254
  /**
208
255
  * Find comments.
209
256
  */
@@ -223,10 +270,10 @@ function findComments(sourceCodeInfo, sourcePath) {
223
270
  }
224
271
  return {
225
272
  leadingDetached: location.leadingDetachedComments,
226
- leading: (0, protobuf_1.isFieldSet)(wkt_1.SourceCodeInfo_LocationDesc, location, "leadingComments")
273
+ leading: (0, protobuf_1.isFieldSet)(location, wkt_1.SourceCodeInfo_LocationDesc.field.leadingComments)
227
274
  ? location.leadingComments
228
275
  : undefined,
229
- trailing: (0, protobuf_1.isFieldSet)(wkt_1.SourceCodeInfo_LocationDesc, location, "trailingComments")
276
+ trailing: (0, protobuf_1.isFieldSet)(location, wkt_1.SourceCodeInfo_LocationDesc.field.trailingComments)
230
277
  ? location.trailingComments
231
278
  : undefined,
232
279
  sourcePath,
@@ -237,23 +284,3 @@ function findComments(sourceCodeInfo, sourcePath) {
237
284
  sourcePath,
238
285
  };
239
286
  }
240
- /**
241
- * The following field numbers are used to find comments in
242
- * google.protobuf.SourceCodeInfo.
243
- */
244
- var FieldNumber;
245
- (function (FieldNumber) {
246
- FieldNumber[FieldNumber["FileDescriptorProto_Package"] = 2] = "FileDescriptorProto_Package";
247
- FieldNumber[FieldNumber["FileDescriptorProto_MessageType"] = 4] = "FileDescriptorProto_MessageType";
248
- FieldNumber[FieldNumber["FileDescriptorProto_EnumType"] = 5] = "FileDescriptorProto_EnumType";
249
- FieldNumber[FieldNumber["FileDescriptorProto_Service"] = 6] = "FileDescriptorProto_Service";
250
- FieldNumber[FieldNumber["FileDescriptorProto_Extension"] = 7] = "FileDescriptorProto_Extension";
251
- FieldNumber[FieldNumber["FileDescriptorProto_Syntax"] = 12] = "FileDescriptorProto_Syntax";
252
- FieldNumber[FieldNumber["DescriptorProto_Field"] = 2] = "DescriptorProto_Field";
253
- FieldNumber[FieldNumber["DescriptorProto_NestedType"] = 3] = "DescriptorProto_NestedType";
254
- FieldNumber[FieldNumber["DescriptorProto_EnumType"] = 4] = "DescriptorProto_EnumType";
255
- FieldNumber[FieldNumber["DescriptorProto_Extension"] = 6] = "DescriptorProto_Extension";
256
- FieldNumber[FieldNumber["DescriptorProto_OneofDecl"] = 8] = "DescriptorProto_OneofDecl";
257
- FieldNumber[FieldNumber["EnumDescriptorProto_Value"] = 2] = "EnumDescriptorProto_Value";
258
- FieldNumber[FieldNumber["ServiceDescriptorProto_Method"] = 2] = "ServiceDescriptorProto_Method";
259
- })(FieldNumber || (FieldNumber = {}));
@@ -1,6 +1,6 @@
1
- import type { SupportedEdition } from "@bufbuild/protobuf";
2
- import type { Schema } from "./ecmascript/schema.js";
3
- import type { FileInfo } from "./ecmascript/generated-file.js";
1
+ import { type SupportedEdition } from "@bufbuild/protobuf";
2
+ import type { Schema } from "./schema.js";
3
+ import type { FileInfo } from "./generated-file.js";
4
4
  import type { Plugin } from "./plugin.js";
5
5
  interface PluginInit {
6
6
  /**
@@ -12,11 +12,11 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
  import { create, protoInt64 } from "@bufbuild/protobuf";
15
- import { minimumEdition as minimumEditionUpstream, maximumEdition as maximumEditionUpstream, } from "@bufbuild/protobuf/reflect";
15
+ import { minimumEdition as minimumEditionUpstream, maximumEdition as maximumEditionUpstream, } from "@bufbuild/protobuf";
16
16
  import { CodeGeneratorResponse_Feature, CodeGeneratorResponseDesc, } from "@bufbuild/protobuf/wkt";
17
- import { createSchema } from "./ecmascript/schema.js";
18
- import { transpile } from "./ecmascript/transpile.js";
19
- import { parseParameter } from "./ecmascript/parameter.js";
17
+ import { createSchema } from "./schema.js";
18
+ import { transpile } from "./transpile.js";
19
+ import { parseParameter } from "./parameter.js";
20
20
  /**
21
21
  * Create a new code generator plugin for ECMAScript.
22
22
  * The plugin can generate JavaScript, TypeScript, or TypeScript declaration
@@ -12,7 +12,7 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
  import { Edition } from "@bufbuild/protobuf/wkt";
15
- import { getPackageComments, getSyntaxComments } from "../source-code-info.js";
15
+ import { getPackageComments, getSyntaxComments, getFeatureOptionStrings, } from "./source-code-info.js";
16
16
  export function makeFilePreamble(file, pluginName, pluginVersion, parameter, tsNoCheck) {
17
17
  const builder = [];
18
18
  const trimSuffix = (str, suffix) => str.endsWith(suffix) ? str.substring(0, str.length - suffix.length) : str;
@@ -61,6 +61,9 @@ export function makeFilePreamble(file, pluginName, pluginVersion, parameter, tsN
61
61
  break;
62
62
  }
63
63
  }
64
+ for (const o of getFeatureOptionStrings(file)) {
65
+ builder.push(`// option ${o};\n`);
66
+ }
64
67
  builder.push("/* eslint-disable */\n");
65
68
  if (tsNoCheck) {
66
69
  builder.push("// @ts-nocheck\n");
@@ -1,4 +1,4 @@
1
- import type { AnyDesc, DescEnum, DescExtension, DescFile, DescMessage, DescService } from "@bufbuild/protobuf";
1
+ import { type AnyDesc, type DescEnum, type DescExtension, type DescFile, type DescMessage, type DescService } from "@bufbuild/protobuf";
2
2
  import type { ImportSymbol } from "./import-symbol.js";
3
3
  import type { Printable } from "./printable.js";
4
4
  import type { RuntimeImports } from "./runtime-imports.js";
@@ -63,7 +63,7 @@ export interface GeneratedFile {
63
63
  * Create a printable export statement. For example:
64
64
  *
65
65
  * ```ts
66
- * f.print(f.exportDecl("abstract class", "MyClass"), " {}")
66
+ * f.print(f.export("abstract class", "MyClass"), " {}")
67
67
  * ```
68
68
  *
69
69
  * Will generate as:
@@ -75,7 +75,7 @@ export interface GeneratedFile {
75
75
  * statement. If the plugin option `js_import_style=legacy_commonjs` is set,
76
76
  * exports will automatically be generated for CommonJS.
77
77
  */
78
- exportDecl(declaration: string, name: string): Printable;
78
+ export(declaration: string, name: string): Printable;
79
79
  /**
80
80
  * Import a message or enumeration generated by protoc-gen-es.
81
81
  */