@typespec/protobuf 0.49.0-dev.3 → 0.49.0-dev.5

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 (43) hide show
  1. package/.rush/temp/package-deps_build.json +28 -26
  2. package/.rush/temp/shrinkwrap-deps.json +0 -3
  3. package/dist/src/ast.d.ts +29 -8
  4. package/dist/src/ast.d.ts.map +1 -1
  5. package/dist/src/ast.js.map +1 -1
  6. package/dist/src/transform/index.d.ts.map +1 -1
  7. package/dist/src/transform/index.js +13 -2
  8. package/dist/src/transform/index.js.map +1 -1
  9. package/dist/src/write.d.ts +0 -6
  10. package/dist/src/write.d.ts.map +1 -1
  11. package/dist/src/write.js +63 -30
  12. package/dist/src/write.js.map +1 -1
  13. package/lib/proto.tsp +5 -0
  14. package/package.json +1 -1
  15. package/src/ast.ts +33 -8
  16. package/src/transform/index.ts +17 -1
  17. package/src/write.ts +81 -30
  18. package/temp/tsconfig.tsbuildinfo +1 -1
  19. package/test/scenarios/addressbook/output/@typespec/protobuf/addressbook.proto +1 -1
  20. package/test/scenarios/addressbook/output/@typespec/protobuf/main.proto +1 -1
  21. package/test/scenarios/anonymous-package/output/@typespec/protobuf/main.proto +1 -1
  22. package/test/scenarios/array/output/@typespec/protobuf/com/azure/test.proto +1 -1
  23. package/test/scenarios/cross package references/output/@typespec/protobuf/A.proto +1 -1
  24. package/test/scenarios/cross package references/output/@typespec/protobuf/B.proto +1 -1
  25. package/test/scenarios/derived-scalar/output/@typespec/protobuf/com/azure/Test.proto +1 -1
  26. package/test/scenarios/doc/input/main.tsp +67 -0
  27. package/test/scenarios/doc/output/@typespec/protobuf/com/azure/Test.proto +35 -0
  28. package/test/scenarios/empty/output/@typespec/protobuf/main.proto +1 -1
  29. package/test/scenarios/enum/output/@typespec/protobuf/main.proto +1 -1
  30. package/test/scenarios/extern/output/@typespec/protobuf/main.proto +1 -1
  31. package/test/scenarios/inferred-message-names/output/@typespec/protobuf/com/azure/test.proto +1 -1
  32. package/test/scenarios/intrinsics/output/@typespec/protobuf/com/azure/Test.proto +1 -1
  33. package/test/scenarios/map/output/@typespec/protobuf/main.proto +1 -1
  34. package/test/scenarios/name-collision/output/@typespec/protobuf/main.proto +1 -1
  35. package/test/scenarios/omit/output/@typespec/protobuf/main.proto +1 -1
  36. package/test/scenarios/omit-off/output/@typespec/protobuf/main.proto +1 -1
  37. package/test/scenarios/options/output/@typespec/protobuf/com/azure/Test.proto +1 -1
  38. package/test/scenarios/reserved fields/output/@typespec/protobuf/main.proto +1 -1
  39. package/test/scenarios/simple/output/@typespec/protobuf/com/azure/Test.proto +1 -1
  40. package/test/scenarios/simple-no-service/output/@typespec/protobuf/com/azure/Test.proto +1 -1
  41. package/test/scenarios/streams/output/@typespec/protobuf/main.proto +1 -1
  42. package/.rush/temp/operation/build/all.log +0 -1
  43. package/.rush/temp/operation/build/state.json +0 -3
package/dist/src/write.js CHANGED
@@ -2,20 +2,17 @@
2
2
  // Licensed under the MIT license.
3
3
  import { matchType, } from "./ast.js";
4
4
  // This module defines how to emit the text representation of a ProtoFile AST.
5
- /**
6
- * Header for the top of all emitted proto files.
7
- *
8
- * We only support Protobuf 3 syntax.
9
- */
10
- export const PROTO_HEADER = `/* Generated by Microsoft TypeSpec */
11
-
12
- syntax = "proto3";
13
- `;
5
+ const PROTO_MAX_ONE_LINE_DOC_LENGTH = 80;
14
6
  /**
15
7
  * Write the given `file` to a string.
16
8
  */
17
9
  export function writeProtoFile(file) {
18
- let result = PROTO_HEADER;
10
+ let result = "// Generated by Microsoft TypeSpec\n";
11
+ let docComment = collect(writeBlockDocumentationComment(file)).join("\n");
12
+ if (docComment.length > 0)
13
+ docComment = "\n" + docComment;
14
+ result += docComment;
15
+ result += '\nsyntax = "proto3";\n';
19
16
  if (file.package)
20
17
  result += `\npackage ${file.package};\n`;
21
18
  for (const _import of file.imports) {
@@ -32,32 +29,35 @@ export function writeProtoFile(file) {
32
29
  if (opts.length > 0)
33
30
  result += "\n";
34
31
  for (const decl of file.declarations) {
35
- result += "\n" + collect(writeDeclaration(decl)).join("\n") + "\n";
32
+ result += "\n" + collect(writeDeclaration(decl, 0)).join("\n") + "\n";
36
33
  }
37
34
  return result;
38
35
  }
39
36
  /**
40
37
  * Write the given `decl` to a line iterable.
41
38
  */
42
- function* writeDeclaration(decl) {
39
+ function* writeDeclaration(decl, indentLevel) {
43
40
  switch (decl.kind) {
44
41
  case "message":
45
- yield* writeMessage(decl);
42
+ yield* writeMessage(decl, indentLevel);
46
43
  return;
47
44
  case "service":
48
- yield* writeService(decl);
45
+ yield* writeService(decl, indentLevel);
49
46
  return;
50
47
  case "field":
51
- yield writeField(decl);
48
+ yield* writeField(decl, indentLevel);
52
49
  return;
53
50
  case "oneof":
54
- yield* writeOneOf(decl);
51
+ yield* writeOneOf(decl, indentLevel);
55
52
  return;
56
53
  case "enum":
57
- yield* writeEnum(decl);
54
+ yield* writeEnum(decl, indentLevel);
55
+ return;
56
+ case "variant":
57
+ yield* writeVariant(decl, indentLevel);
58
58
  return;
59
59
  case "method":
60
- yield writeMethod(decl);
60
+ yield* writeMethod(decl);
61
61
  return;
62
62
  /* c8 ignore next 5 */
63
63
  default:
@@ -68,14 +68,15 @@ function* writeDeclaration(decl) {
68
68
  /**
69
69
  * Write the given message `decl` to a line iterable.
70
70
  */
71
- function* writeMessage(decl) {
71
+ function* writeMessage(decl, indentLevel) {
72
72
  var _a;
73
+ yield* writeBlockDocumentationComment(decl);
73
74
  const head = `message ${decl.name} {`;
74
75
  const tail = "}";
75
76
  if (decl.declarations.length > 0 || ((_a = decl.reservations) === null || _a === void 0 ? void 0 : _a.length)) {
76
77
  yield head;
77
78
  yield* indent(writeReservations(decl));
78
- yield* indent(flatMap(decl.declarations, writeDeclaration));
79
+ yield* indent(flatMap(decl.declarations, (decl) => writeDeclaration(decl, indentLevel + 1)));
79
80
  yield tail;
80
81
  }
81
82
  else
@@ -95,43 +96,52 @@ function* writeReservations(decl) {
95
96
  yield "";
96
97
  }
97
98
  }
98
- function* writeService(decl) {
99
+ function* writeService(decl, indentLevel) {
100
+ yield* writeBlockDocumentationComment(decl);
99
101
  const head = `service ${decl.name} {`;
100
102
  const tail = "}";
101
103
  if (decl.operations.length > 0) {
102
104
  yield head;
103
- yield* indent(flatMap(decl.operations, writeDeclaration));
105
+ yield* indent(flatMap(decl.operations, (decl) => writeDeclaration(decl, indentLevel + 1)));
104
106
  yield tail;
105
107
  }
106
108
  else
107
109
  yield head + tail;
108
110
  }
109
- function writeMethod(decl) {
111
+ function* writeMethod(decl) {
112
+ yield* writeBlockDocumentationComment(decl);
110
113
  const [inStream, outStream] = [
111
114
  decl.stream & 2 /* StreamingMode.In */,
112
115
  decl.stream & 1 /* StreamingMode.Out */,
113
116
  ].map((v) => (v ? "stream " : ""));
114
- return `rpc ${decl.name}(${inStream}${writeType(decl.input)}) returns (${outStream}${writeType(decl.returns)});`;
117
+ yield `rpc ${decl.name}(${inStream}${writeType(decl.input)}) returns (${outStream}${writeType(decl.returns)});`;
115
118
  }
116
- function* writeOneOf(decl) {
119
+ function* writeOneOf(decl, indentLevel) {
120
+ yield* writeBlockDocumentationComment(decl);
117
121
  // OneOf declarations must have at least one element, so no need to check for declarations
118
122
  yield `oneof ${decl.name} {`;
119
- yield* indent(flatMap(decl.declarations, writeDeclaration));
123
+ yield* indent(flatMap(decl.declarations, (decl) => writeDeclaration(decl, indentLevel + 1)));
120
124
  yield "}";
121
125
  }
122
- function* writeEnum(decl) {
126
+ function* writeEnum(decl, indentLevel) {
127
+ yield* writeBlockDocumentationComment(decl);
123
128
  yield `enum ${decl.name} {`;
124
129
  if (decl.allowAlias) {
125
130
  yield " option allow_alias = true;";
126
131
  if (decl.variants.length > 0)
127
132
  yield "";
128
133
  }
129
- yield* indent(flatMap(decl.variants, ([name, idx]) => `${name} = ${idx};`));
134
+ yield* indent(flatMap(decl.variants, (decl) => writeDeclaration(decl, indentLevel + 1)));
130
135
  yield "}";
131
136
  }
132
- function writeField(decl) {
137
+ function writeVariant(decl, indentLevel) {
138
+ const output = `${decl.name} = ${decl.value};`;
139
+ return writeDocumentationCommentFlexible(decl, output, indentLevel);
140
+ }
141
+ function writeField(decl, indentLevel) {
133
142
  const prefix = decl.repeated ? "repeated " : "";
134
- return prefix + `${writeType(decl.type)} ${decl.name} = ${decl.index};`;
143
+ const output = prefix + `${writeType(decl.type)} ${decl.name} = ${decl.index};`;
144
+ return writeDocumentationCommentFlexible(decl, output, indentLevel);
135
145
  }
136
146
  function writeType(type) {
137
147
  return matchType(type, {
@@ -157,6 +167,29 @@ function* indent(it, depth = 2) {
157
167
  yield value;
158
168
  }
159
169
  }
170
+ /**
171
+ * Writes a block comment from the given declaration.
172
+ */
173
+ function* writeBlockDocumentationComment(decl) {
174
+ var _a, _b;
175
+ yield* (_b = (_a = decl.doc) === null || _a === void 0 ? void 0 : _a.trim().split("\n").map((line) => `// ${line}`)) !== null && _b !== void 0 ? _b : [];
176
+ }
177
+ /**
178
+ * Writes a block comment or inline postfix comment depending on the length of the content.
179
+ */
180
+ function* writeDocumentationCommentFlexible(decl, output, indentLevel) {
181
+ var _a, _b;
182
+ const docComment = (_a = decl.doc) === null || _a === void 0 ? void 0 : _a.trim();
183
+ const docCommentIsOneLine = docComment && !(docComment === null || docComment === void 0 ? void 0 : docComment.includes("\n"));
184
+ const fullLength = indentLevel * 2 + output.length + 1 + ((_b = docComment === null || docComment === void 0 ? void 0 : docComment.length) !== null && _b !== void 0 ? _b : 0);
185
+ if (docCommentIsOneLine && fullLength <= PROTO_MAX_ONE_LINE_DOC_LENGTH) {
186
+ yield output + " // " + decl.doc;
187
+ }
188
+ else {
189
+ yield* writeBlockDocumentationComment(decl);
190
+ yield output;
191
+ }
192
+ }
160
193
  /**
161
194
  * A version of flatMap that works with generic iterables.
162
195
  *
@@ -1 +1 @@
1
- {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/write.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EACL,SAAS,GAWV,MAAM,UAAU,CAAC;AAElB,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;;;CAG3B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAe;IAC5C,IAAI,MAAM,GAAG,YAAY,CAAC;IAE1B,IAAI,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,aAAa,IAAI,CAAC,OAAO,KAAK,CAAC;IAE3D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE;QAClC,MAAM,IAAI,aAAa,OAAO,IAAI,CAAC;KACpC;IAED,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,IAAI,CAAC;IAE5C,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,EAAE;QACpC,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QACtF,MAAM,IAAI,YAAY,IAAI,MAAM,KAAK,GAAG,CAAC;KAC1C;IAED,yEAAyE;IACzE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,IAAI,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;QACpC,MAAM,IAAI,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KACpE;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,QAAQ,CAAC,CAAC,gBAAgB,CAAC,IAAsB;IAC/C,QAAQ,IAAI,CAAC,IAAI,EAAE;QACjB,KAAK,SAAS;YACZ,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO;QACT,KAAK,SAAS;YACZ,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO;QACT,KAAK,OAAO;YACV,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO;QACT,KAAK,OAAO;YACV,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACT,KAAK,MAAM;YACT,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACvB,OAAO;QACT,KAAK,QAAQ;YACX,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACT,sBAAsB;QACtB;YACE,MAAM,SAAS,GAAU,IAAI,CAAC;YAC9B,MAAM,SAAS,CAAC;KACnB;AACH,CAAC;AAED;;GAEG;AACH,QAAQ,CAAC,CAAC,YAAY,CAAC,IAA6B;;IAClD,MAAM,IAAI,GAAG,WAAW,IAAI,CAAC,IAAI,IAAI,CAAC;IACtC,MAAM,IAAI,GAAG,GAAG,CAAC;IAEjB,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,KAAI,MAAA,IAAI,CAAC,YAAY,0CAAE,MAAM,CAAA,EAAE;QAC7D,MAAM,IAAI,CAAC;QACX,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC;KACZ;;QAAM,MAAM,IAAI,GAAG,IAAI,CAAC;AAC3B,CAAC;AAED,QAAQ,CAAC,CAAC,iBAAiB,CAAC,IAA6B;;IACvD,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,SAAS,CAClD,MAAA,IAAI,CAAC,YAAY,mCAAI,EAAE,EACvB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC,EACxF;QACE,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChF,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG;KAC1C,CACF,CAAC;IAEF,IAAI,eAAe,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;QACrD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,YAAY,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAChF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,YAAY,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAC5E,MAAM,EAAE,CAAC;KACV;AACH,CAAC;AAED,QAAQ,CAAC,CAAC,YAAY,CAAC,IAA6B;IAClD,MAAM,IAAI,GAAG,WAAW,IAAI,CAAC,IAAI,IAAI,CAAC;IACtC,MAAM,IAAI,GAAG,GAAG,CAAC;IAEjB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;QAC9B,MAAM,IAAI,CAAC;QACX,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC;KACZ;;QAAM,MAAM,IAAI,GAAG,IAAI,CAAC;AAC3B,CAAC;AAED,SAAS,WAAW,CAAC,IAA4B;IAC/C,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG;QAC5B,IAAI,CAAC,MAAM,2BAAmB;QAC9B,IAAI,CAAC,MAAM,4BAAoB;KAChC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnC,OAAO,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,SAAS,GAAG,SAAS,CAC5F,IAAI,CAAC,OAAO,CACb,IAAI,CAAC;AACR,CAAC;AAED,QAAQ,CAAC,CAAC,UAAU,CAAC,IAA2B;IAC9C,0FAA0F;IAC1F,MAAM,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC;IAC7B,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC5D,MAAM,GAAG,CAAC;AACZ,CAAC;AAED,QAAQ,CAAC,CAAC,SAAS,CAAC,IAA0B;IAC5C,MAAM,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC;IAC5B,IAAI,IAAI,CAAC,UAAU,EAAE;QACnB,MAAM,8BAA8B,CAAC;QAErC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,EAAE,CAAC;KACxC;IACD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;IAC5E,MAAM,GAAG,CAAC;AACZ,CAAC;AAED,SAAS,UAAU,CAAC,IAA2B;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,OAAO,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,KAAK,GAAG,CAAC;AAC1E,CAAC;AAED,SAAS,SAAS,CAAC,IAAe;IAChC,OAAO,SAAS,CAAC,IAAI,EAAE;QACrB,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG;QAC3C,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACb,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;KACjB,CAAC,CAAC;AACL,CAAC;AAED,gBAAgB;AAEhB;;;;;;GAMG;AACH,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAoB,EAAE,QAAgB,CAAC;IACtD,KAAK,MAAM,KAAK,IAAI,EAAE,EAAE;QACtB,IAAI,KAAK,KAAK,EAAE,EAAE;YAChB,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;SACjC;;YAAM,MAAM,KAAK,CAAC;KACpB;AACH,CAAC;AAED;;;;;GAKG;AACH,QAAQ,CAAC,CAAC,OAAO,CAAS,EAAgB,EAAE,CAA+B;IACzE,KAAK,MAAM,KAAK,IAAI,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,EAAE;YAC9E,KAAK,CAAC,CAAC,MAAsB,CAAC;SAC/B;aAAM;YACL,MAAM,MAAY,CAAC;SACpB;KACF;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,OAAO,CAAI,EAAe;IACjC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAChB,MAAqB,EACrB,MAAmC,EACnC,SAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAE3E,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;QAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAQ,CAAC,CAAC;KAC5C;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,aAAa"}
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/write.ts"],"names":[],"mappings":"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"}
package/lib/proto.tsp CHANGED
@@ -74,6 +74,7 @@ namespace WellKnown {
74
74
  * Uses variable-length encoding. These more efficiently encode negative numbers than regular int32s.
75
75
  */
76
76
  scalar sint32 extends int32;
77
+
77
78
  /**
78
79
  * A signed 64-bit integer that will use the `sint64` encoding when used in a Protobuf message.
79
80
  *
@@ -82,6 +83,7 @@ scalar sint32 extends int32;
82
83
  * Uses variable-length encoding. These more efficiently encode negative numbers than regular `int64s`.
83
84
  */
84
85
  scalar sint64 extends int64;
86
+
85
87
  /**
86
88
  * A signed 32-bit integer that will use the `sfixed32` encoding when used in a Protobuf message.
87
89
  *
@@ -90,6 +92,7 @@ scalar sint64 extends int64;
90
92
  * Always four bytes.
91
93
  */
92
94
  scalar sfixed32 extends int32;
95
+
93
96
  /**
94
97
  * A signed 64-bit integer that will use the `sfixed64` encoding when used in a Protobuf message.
95
98
  *
@@ -98,6 +101,7 @@ scalar sfixed32 extends int32;
98
101
  * Always eight bytes.
99
102
  */
100
103
  scalar sfixed64 extends int64;
104
+
101
105
  /**
102
106
  * An unsigned 32-bit integer that will use the `fixed32` encoding when used in a Protobuf message.
103
107
  *
@@ -106,6 +110,7 @@ scalar sfixed64 extends int64;
106
110
  * Always four bytes. More efficient than `uint32` if values are often greater than 2<sup>28</sup>.
107
111
  */
108
112
  scalar fixed32 extends uint32;
113
+
109
114
  /**
110
115
  * An unsigned 64-bit integer that will use the `fixed64` encoding when used in a Protobuf message.
111
116
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typespec/protobuf",
3
- "version": "0.49.0-dev.3",
3
+ "version": "0.49.0-dev.5",
4
4
  "author": "Microsoft Corporation",
5
5
  "description": "TypeSpec library and emitter for Protobuf (gRPC)",
6
6
  "homepage": "https://github.com/microsoft/typespec",
package/src/ast.ts CHANGED
@@ -35,6 +35,11 @@ export interface ProtoFile {
35
35
  * The original namespace node from which this ProtoFile originated.
36
36
  */
37
37
  source: Namespace;
38
+
39
+ /**
40
+ * The package-level documentation comment, if any.
41
+ */
42
+ doc?: string | undefined;
38
43
  }
39
44
 
40
45
  /**
@@ -66,7 +71,8 @@ export type ProtoDeclaration =
66
71
  | ProtoFieldDeclaration
67
72
  | ProtoOneOfDeclaration
68
73
  | ProtoEnumDeclaration
69
- | ProtoMethodDeclaration;
74
+ | ProtoMethodDeclaration
75
+ | ProtoEnumVariantDeclaration;
70
76
 
71
77
  /**
72
78
  * A Protobuf scalar type.
@@ -187,10 +193,20 @@ export function matchType<Result>(type: ProtoType, pattern: ProtoTypeMatchPatter
187
193
  }
188
194
  }
189
195
 
196
+ /**
197
+ * Elements common to all protobuf declarations.
198
+ */
199
+ export interface ProtoDeclarationCommon {
200
+ /**
201
+ * Documentation comment text, if any.
202
+ */
203
+ doc?: string | undefined;
204
+ }
205
+
190
206
  /**
191
207
  * A `service` declaration.
192
208
  */
193
- export interface ProtoServiceDeclaration {
209
+ export interface ProtoServiceDeclaration extends ProtoDeclarationCommon {
194
210
  kind: "service";
195
211
  name: string;
196
212
  operations: ProtoMethodDeclaration[];
@@ -209,7 +225,7 @@ export const enum StreamingMode {
209
225
  /**
210
226
  * An `rfc` method declaration.
211
227
  */
212
- export interface ProtoMethodDeclaration {
228
+ export interface ProtoMethodDeclaration extends ProtoDeclarationCommon {
213
229
  kind: "method";
214
230
  stream: StreamingMode;
215
231
  name: string;
@@ -229,7 +245,7 @@ export type ProtoMessageBodyDeclaration =
229
245
  /**
230
246
  * A `message` declaration.
231
247
  */
232
- export interface ProtoMessageDeclaration {
248
+ export interface ProtoMessageDeclaration extends ProtoDeclarationCommon {
233
249
  kind: "message";
234
250
  name: string;
235
251
  declarations: Array<ProtoMessageBodyDeclaration>;
@@ -239,7 +255,7 @@ export interface ProtoMessageDeclaration {
239
255
  /**
240
256
  * A field declaration within a message.
241
257
  */
242
- export interface ProtoFieldDeclaration {
258
+ export interface ProtoFieldDeclaration extends ProtoDeclarationCommon {
243
259
  kind: "field";
244
260
  name: string;
245
261
  /**
@@ -262,7 +278,7 @@ export interface DefaultFieldOptions {
262
278
  /**
263
279
  * A `one_of` declaration.
264
280
  */
265
- export interface ProtoOneOfDeclaration {
281
+ export interface ProtoOneOfDeclaration extends ProtoDeclarationCommon {
266
282
  kind: "oneof";
267
283
  name: string;
268
284
  declarations: ProtoFieldDeclaration[];
@@ -271,9 +287,18 @@ export interface ProtoOneOfDeclaration {
271
287
  /**
272
288
  * An `enum` declaration.
273
289
  */
274
- export interface ProtoEnumDeclaration {
290
+ export interface ProtoEnumDeclaration extends ProtoDeclarationCommon {
275
291
  kind: "enum";
276
292
  name: string;
277
293
  allowAlias?: boolean;
278
- variants: [string, number][];
294
+ variants: ProtoEnumVariantDeclaration[];
295
+ }
296
+
297
+ /**
298
+ * A variant within an `enum` declaration.
299
+ */
300
+ export interface ProtoEnumVariantDeclaration extends ProtoDeclarationCommon {
301
+ kind: "variant";
302
+ name: string;
303
+ value: number;
279
304
  }
@@ -5,6 +5,7 @@ import {
5
5
  DiagnosticTarget,
6
6
  Enum,
7
7
  formatDiagnostic,
8
+ getDoc,
8
9
  getEffectiveModelType,
9
10
  getTypeName,
10
11
  Interface,
@@ -26,6 +27,7 @@ import {
26
27
  map,
27
28
  matchType,
28
29
  ProtoEnumDeclaration,
30
+ ProtoEnumVariantDeclaration,
29
31
  ProtoFieldDeclaration,
30
32
  ProtoFile,
31
33
  ProtoMap,
@@ -206,6 +208,8 @@ function tspToProto(program: Program, emitterOptions: ProtobufEmitterOptions): P
206
208
 
207
209
  declarations: declarationMap.get(namespace),
208
210
  source: namespace,
211
+
212
+ doc: getDoc(program, namespace),
209
213
  } as ProtoFile;
210
214
  });
211
215
 
@@ -261,6 +265,7 @@ function tspToProto(program: Program, emitterOptions: ProtobufEmitterOptions): P
261
265
  name: iface.name,
262
266
  // The service's methods are just projections of the interface operations.
263
267
  operations: [...iface.operations.values()].map(toMethodFromOperation),
268
+ doc: getDoc(program, iface),
264
269
  });
265
270
  }
266
271
  }
@@ -297,6 +302,7 @@ function tspToProto(program: Program, emitterOptions: ProtobufEmitterOptions): P
297
302
  operation,
298
303
  operation.returnType as NamespaceTraversable
299
304
  ),
305
+ doc: getDoc(program, operation),
300
306
  };
301
307
  }
302
308
 
@@ -680,6 +686,7 @@ function tspToProto(program: Program, emitterOptions: ProtobufEmitterOptions): P
680
686
  name: model.name,
681
687
  reservations: program.stateMap(state.reserve).get(model),
682
688
  declarations: [...model.properties.values()].map((f) => toMessageBodyDeclaration(f, model)),
689
+ doc: getDoc(program, model),
683
690
  };
684
691
  }
685
692
 
@@ -775,6 +782,7 @@ function tspToProto(program: Program, emitterOptions: ProtobufEmitterOptions): P
775
782
  property.type as NamespaceTraversable
776
783
  ),
777
784
  index: program.stateMap(state.fieldIndex).get(property),
785
+ doc: getDoc(program, property),
778
786
  };
779
787
 
780
788
  // Determine if the property type is an array
@@ -796,7 +804,15 @@ function tspToProto(program: Program, emitterOptions: ProtobufEmitterOptions): P
796
804
  kind: "enum",
797
805
  name: e.name,
798
806
  allowAlias: needsAlias,
799
- variants: [...e.members.values()].map(({ name, value }) => [name, value as number]),
807
+ variants: [...e.members.values()].map(
808
+ (variant): ProtoEnumVariantDeclaration => ({
809
+ kind: "variant",
810
+ name: variant.name,
811
+ value: variant.value as number,
812
+ doc: getDoc(program, variant),
813
+ })
814
+ ),
815
+ doc: getDoc(program, e),
800
816
  };
801
817
  }
802
818
 
package/src/write.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  matchType,
6
6
  ProtoDeclaration,
7
7
  ProtoEnumDeclaration,
8
+ ProtoEnumVariantDeclaration,
8
9
  ProtoFieldDeclaration,
9
10
  ProtoFile,
10
11
  ProtoMessageDeclaration,
@@ -17,21 +18,19 @@ import {
17
18
 
18
19
  // This module defines how to emit the text representation of a ProtoFile AST.
19
20
 
20
- /**
21
- * Header for the top of all emitted proto files.
22
- *
23
- * We only support Protobuf 3 syntax.
24
- */
25
- export const PROTO_HEADER = `/* Generated by Microsoft TypeSpec */
26
-
27
- syntax = "proto3";
28
- `;
21
+ const PROTO_MAX_ONE_LINE_DOC_LENGTH = 80;
29
22
 
30
23
  /**
31
24
  * Write the given `file` to a string.
32
25
  */
33
26
  export function writeProtoFile(file: ProtoFile): string {
34
- let result = PROTO_HEADER;
27
+ let result = "// Generated by Microsoft TypeSpec\n";
28
+
29
+ let docComment = collect(writeBlockDocumentationComment(file)).join("\n");
30
+ if (docComment.length > 0) docComment = "\n" + docComment;
31
+ result += docComment;
32
+
33
+ result += '\nsyntax = "proto3";\n';
35
34
 
36
35
  if (file.package) result += `\npackage ${file.package};\n`;
37
36
 
@@ -51,7 +50,7 @@ export function writeProtoFile(file: ProtoFile): string {
51
50
  if (opts.length > 0) result += "\n";
52
51
 
53
52
  for (const decl of file.declarations) {
54
- result += "\n" + collect(writeDeclaration(decl)).join("\n") + "\n";
53
+ result += "\n" + collect(writeDeclaration(decl, 0)).join("\n") + "\n";
55
54
  }
56
55
 
57
56
  return result;
@@ -60,25 +59,28 @@ export function writeProtoFile(file: ProtoFile): string {
60
59
  /**
61
60
  * Write the given `decl` to a line iterable.
62
61
  */
63
- function* writeDeclaration(decl: ProtoDeclaration): Iterable<string> {
62
+ function* writeDeclaration(decl: ProtoDeclaration, indentLevel: number): Iterable<string> {
64
63
  switch (decl.kind) {
65
64
  case "message":
66
- yield* writeMessage(decl);
65
+ yield* writeMessage(decl, indentLevel);
67
66
  return;
68
67
  case "service":
69
- yield* writeService(decl);
68
+ yield* writeService(decl, indentLevel);
70
69
  return;
71
70
  case "field":
72
- yield writeField(decl);
71
+ yield* writeField(decl, indentLevel);
73
72
  return;
74
73
  case "oneof":
75
- yield* writeOneOf(decl);
74
+ yield* writeOneOf(decl, indentLevel);
76
75
  return;
77
76
  case "enum":
78
- yield* writeEnum(decl);
77
+ yield* writeEnum(decl, indentLevel);
78
+ return;
79
+ case "variant":
80
+ yield* writeVariant(decl, indentLevel);
79
81
  return;
80
82
  case "method":
81
- yield writeMethod(decl);
83
+ yield* writeMethod(decl);
82
84
  return;
83
85
  /* c8 ignore next 5 */
84
86
  default:
@@ -90,14 +92,16 @@ function* writeDeclaration(decl: ProtoDeclaration): Iterable<string> {
90
92
  /**
91
93
  * Write the given message `decl` to a line iterable.
92
94
  */
93
- function* writeMessage(decl: ProtoMessageDeclaration): Iterable<string> {
95
+ function* writeMessage(decl: ProtoMessageDeclaration, indentLevel: number): Iterable<string> {
96
+ yield* writeBlockDocumentationComment(decl);
97
+
94
98
  const head = `message ${decl.name} {`;
95
99
  const tail = "}";
96
100
 
97
101
  if (decl.declarations.length > 0 || decl.reservations?.length) {
98
102
  yield head;
99
103
  yield* indent(writeReservations(decl));
100
- yield* indent(flatMap(decl.declarations, writeDeclaration));
104
+ yield* indent(flatMap(decl.declarations, (decl) => writeDeclaration(decl, indentLevel + 1)));
101
105
  yield tail;
102
106
  } else yield head + tail;
103
107
  }
@@ -119,49 +123,65 @@ function* writeReservations(decl: ProtoMessageDeclaration): Iterable<string> {
119
123
  }
120
124
  }
121
125
 
122
- function* writeService(decl: ProtoServiceDeclaration): Iterable<string> {
126
+ function* writeService(decl: ProtoServiceDeclaration, indentLevel: number): Iterable<string> {
127
+ yield* writeBlockDocumentationComment(decl);
128
+
123
129
  const head = `service ${decl.name} {`;
124
130
  const tail = "}";
125
131
 
126
132
  if (decl.operations.length > 0) {
127
133
  yield head;
128
- yield* indent(flatMap(decl.operations, writeDeclaration));
134
+ yield* indent(flatMap(decl.operations, (decl) => writeDeclaration(decl, indentLevel + 1)));
129
135
  yield tail;
130
136
  } else yield head + tail;
131
137
  }
132
138
 
133
- function writeMethod(decl: ProtoMethodDeclaration): string {
139
+ function* writeMethod(decl: ProtoMethodDeclaration): Iterable<string> {
140
+ yield* writeBlockDocumentationComment(decl);
141
+
134
142
  const [inStream, outStream] = [
135
143
  decl.stream & StreamingMode.In,
136
144
  decl.stream & StreamingMode.Out,
137
145
  ].map((v) => (v ? "stream " : ""));
138
146
 
139
- return `rpc ${decl.name}(${inStream}${writeType(decl.input)}) returns (${outStream}${writeType(
147
+ yield `rpc ${decl.name}(${inStream}${writeType(decl.input)}) returns (${outStream}${writeType(
140
148
  decl.returns
141
149
  )});`;
142
150
  }
143
151
 
144
- function* writeOneOf(decl: ProtoOneOfDeclaration): Iterable<string> {
152
+ function* writeOneOf(decl: ProtoOneOfDeclaration, indentLevel: number): Iterable<string> {
153
+ yield* writeBlockDocumentationComment(decl);
154
+
145
155
  // OneOf declarations must have at least one element, so no need to check for declarations
146
156
  yield `oneof ${decl.name} {`;
147
- yield* indent(flatMap(decl.declarations, writeDeclaration));
157
+ yield* indent(flatMap(decl.declarations, (decl) => writeDeclaration(decl, indentLevel + 1)));
148
158
  yield "}";
149
159
  }
150
160
 
151
- function* writeEnum(decl: ProtoEnumDeclaration): Iterable<string> {
161
+ function* writeEnum(decl: ProtoEnumDeclaration, indentLevel: number): Iterable<string> {
162
+ yield* writeBlockDocumentationComment(decl);
163
+
152
164
  yield `enum ${decl.name} {`;
153
165
  if (decl.allowAlias) {
154
166
  yield " option allow_alias = true;";
155
167
 
156
168
  if (decl.variants.length > 0) yield "";
157
169
  }
158
- yield* indent(flatMap(decl.variants, ([name, idx]) => `${name} = ${idx};`));
170
+ yield* indent(flatMap(decl.variants, (decl) => writeDeclaration(decl, indentLevel + 1)));
159
171
  yield "}";
160
172
  }
161
173
 
162
- function writeField(decl: ProtoFieldDeclaration): string {
174
+ function writeVariant(decl: ProtoEnumVariantDeclaration, indentLevel: number): Iterable<string> {
175
+ const output = `${decl.name} = ${decl.value};`;
176
+
177
+ return writeDocumentationCommentFlexible(decl, output, indentLevel);
178
+ }
179
+
180
+ function writeField(decl: ProtoFieldDeclaration, indentLevel: number): Iterable<string> {
163
181
  const prefix = decl.repeated ? "repeated " : "";
164
- return prefix + `${writeType(decl.type)} ${decl.name} = ${decl.index};`;
182
+ const output = prefix + `${writeType(decl.type)} ${decl.name} = ${decl.index};`;
183
+
184
+ return writeDocumentationCommentFlexible(decl, output, indentLevel);
165
185
  }
166
186
 
167
187
  function writeType(type: ProtoType): string {
@@ -189,6 +209,37 @@ function* indent(it: Iterable<string>, depth: number = 2): Iterable<string> {
189
209
  }
190
210
  }
191
211
 
212
+ /**
213
+ * Writes a block comment from the given declaration.
214
+ */
215
+ function* writeBlockDocumentationComment(decl: ProtoDeclaration | ProtoFile): Iterable<string> {
216
+ yield* decl.doc
217
+ ?.trim()
218
+ .split("\n")
219
+ .map((line) => `// ${line}`) ?? [];
220
+ }
221
+
222
+ /**
223
+ * Writes a block comment or inline postfix comment depending on the length of the content.
224
+ */
225
+ function* writeDocumentationCommentFlexible(
226
+ decl: ProtoDeclaration,
227
+ output: string,
228
+ indentLevel: number
229
+ ): Iterable<string> {
230
+ const docComment = decl.doc?.trim();
231
+ const docCommentIsOneLine = docComment && !docComment?.includes("\n");
232
+
233
+ const fullLength = indentLevel * 2 + output.length + 1 + (docComment?.length ?? 0);
234
+
235
+ if (docCommentIsOneLine && fullLength <= PROTO_MAX_ONE_LINE_DOC_LENGTH) {
236
+ yield output + " // " + decl.doc;
237
+ } else {
238
+ yield* writeBlockDocumentationComment(decl);
239
+ yield output;
240
+ }
241
+ }
242
+
192
243
  /**
193
244
  * A version of flatMap that works with generic iterables.
194
245
  *