@bufbuild/protobuf 2.12.0 → 2.13.0

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 (224) hide show
  1. package/README.md +5 -5
  2. package/dist/commonjs/codegenv1/boot.d.ts +1 -0
  3. package/dist/{cjs/codegenv1/types.js → commonjs/codegenv1/boot.js} +3 -7
  4. package/dist/{cjs → commonjs}/codegenv1/symbols.d.ts +5 -0
  5. package/dist/{cjs → commonjs}/codegenv1/types.d.ts +9 -5
  6. package/dist/commonjs/codegenv2/enum.d.ts +29 -0
  7. package/dist/{cjs → commonjs}/codegenv2/enum.js +18 -0
  8. package/dist/{cjs → commonjs}/codegenv2/symbols.d.ts +10 -0
  9. package/dist/{cjs → commonjs}/codegenv2/symbols.js +2 -0
  10. package/dist/{cjs → commonjs}/codegenv2/types.d.ts +9 -5
  11. package/dist/{cjs → commonjs}/create.js +3 -3
  12. package/dist/{cjs → commonjs}/descriptors.d.ts +2 -2
  13. package/dist/{cjs → commonjs}/equals.d.ts +8 -3
  14. package/dist/{cjs → commonjs}/equals.js +8 -3
  15. package/dist/{cjs → commonjs}/extensions.d.ts +2 -1
  16. package/dist/{cjs → commonjs}/extensions.js +3 -4
  17. package/dist/{cjs → commonjs}/from-binary.d.ts +16 -2
  18. package/dist/{cjs → commonjs}/from-binary.js +30 -24
  19. package/dist/{cjs → commonjs}/from-json.d.ts +19 -2
  20. package/dist/{cjs → commonjs}/from-json.js +174 -54
  21. package/dist/{cjs → commonjs}/index.d.ts +1 -0
  22. package/dist/{cjs → commonjs}/index.js +1 -0
  23. package/dist/commonjs/json-value.js +15 -0
  24. package/dist/commonjs/package.json +4 -0
  25. package/dist/{cjs → commonjs}/proto-int64.js +1 -0
  26. package/dist/{cjs → commonjs}/reflect/reflect-check.js +3 -1
  27. package/dist/{cjs → commonjs}/reflect/reflect.js +3 -2
  28. package/dist/commonjs/reflect/scalar.d.ts +43 -0
  29. package/dist/{cjs → commonjs}/reflect/scalar.js +33 -6
  30. package/dist/{cjs → commonjs}/reflect/unsafe.js +1 -1
  31. package/dist/{cjs → commonjs}/registry.js +20 -20
  32. package/dist/{cjs → commonjs}/to-binary.js +1 -1
  33. package/dist/{cjs → commonjs}/to-json.js +2 -2
  34. package/dist/commonjs/txtpb/from-text.d.ts +35 -0
  35. package/dist/commonjs/txtpb/from-text.js +684 -0
  36. package/dist/commonjs/txtpb/index.d.ts +4 -0
  37. package/dist/commonjs/txtpb/index.js +21 -0
  38. package/dist/commonjs/txtpb/is-group-like.d.ts +19 -0
  39. package/dist/commonjs/txtpb/is-group-like.js +47 -0
  40. package/dist/commonjs/txtpb/reader.d.ts +91 -0
  41. package/dist/commonjs/txtpb/reader.js +481 -0
  42. package/dist/commonjs/txtpb/to-text.d.ts +34 -0
  43. package/dist/commonjs/txtpb/to-text.js +358 -0
  44. package/dist/commonjs/txtpb/writer.d.ts +76 -0
  45. package/dist/commonjs/txtpb/writer.js +220 -0
  46. package/dist/{cjs → commonjs}/types.d.ts +7 -0
  47. package/dist/{cjs/codegenv2 → commonjs}/types.js +0 -7
  48. package/dist/commonjs/unknown-enum.d.ts +10 -0
  49. package/dist/commonjs/unknown-enum.js +26 -0
  50. package/dist/{cjs → commonjs}/wire/binary-encoding.d.ts +4 -2
  51. package/dist/{cjs → commonjs}/wire/binary-encoding.js +8 -3
  52. package/dist/{cjs → commonjs}/wire/size-delimited.d.ts +19 -1
  53. package/dist/{cjs → commonjs}/wire/size-delimited.js +54 -16
  54. package/dist/esm/codegenv1/boot.d.ts +1 -0
  55. package/dist/esm/codegenv1/boot.js +14 -0
  56. package/dist/esm/codegenv1/symbols.d.ts +5 -0
  57. package/dist/esm/codegenv1/types.d.ts +9 -5
  58. package/dist/esm/codegenv1/types.js +0 -7
  59. package/dist/esm/codegenv2/enum.d.ts +15 -4
  60. package/dist/esm/codegenv2/enum.js +17 -0
  61. package/dist/esm/codegenv2/symbols.d.ts +10 -0
  62. package/dist/esm/codegenv2/symbols.js +2 -0
  63. package/dist/esm/codegenv2/types.d.ts +9 -5
  64. package/dist/esm/codegenv2/types.js +0 -7
  65. package/dist/esm/create.js +3 -3
  66. package/dist/esm/descriptors.d.ts +2 -2
  67. package/dist/esm/equals.d.ts +8 -3
  68. package/dist/esm/equals.js +8 -3
  69. package/dist/esm/extensions.d.ts +2 -1
  70. package/dist/esm/extensions.js +4 -5
  71. package/dist/esm/from-binary.d.ts +16 -2
  72. package/dist/esm/from-binary.js +29 -24
  73. package/dist/esm/from-json.d.ts +19 -2
  74. package/dist/esm/from-json.js +174 -54
  75. package/dist/esm/index.d.ts +1 -0
  76. package/dist/esm/index.js +1 -0
  77. package/dist/esm/package.json +4 -0
  78. package/dist/esm/proto-int64.js +1 -0
  79. package/dist/esm/reflect/reflect-check.js +3 -1
  80. package/dist/esm/reflect/reflect.js +3 -2
  81. package/dist/esm/reflect/scalar.d.ts +27 -5
  82. package/dist/esm/reflect/scalar.js +33 -6
  83. package/dist/esm/reflect/unsafe.js +1 -1
  84. package/dist/esm/registry.js +20 -20
  85. package/dist/esm/to-binary.js +1 -1
  86. package/dist/esm/to-json.js +2 -2
  87. package/dist/esm/txtpb/from-text.d.ts +35 -0
  88. package/dist/esm/txtpb/from-text.js +680 -0
  89. package/dist/esm/txtpb/index.d.ts +4 -0
  90. package/dist/esm/txtpb/index.js +15 -0
  91. package/dist/esm/txtpb/is-group-like.d.ts +19 -0
  92. package/dist/esm/txtpb/is-group-like.js +44 -0
  93. package/dist/esm/txtpb/reader.d.ts +91 -0
  94. package/dist/esm/txtpb/reader.js +477 -0
  95. package/dist/esm/txtpb/to-text.d.ts +34 -0
  96. package/dist/esm/txtpb/to-text.js +355 -0
  97. package/dist/esm/txtpb/writer.d.ts +76 -0
  98. package/dist/esm/txtpb/writer.js +214 -0
  99. package/dist/esm/types.d.ts +7 -0
  100. package/dist/esm/unknown-enum.d.ts +10 -0
  101. package/dist/esm/unknown-enum.js +23 -0
  102. package/dist/esm/wire/binary-encoding.d.ts +4 -2
  103. package/dist/esm/wire/binary-encoding.js +8 -3
  104. package/dist/esm/wire/size-delimited.d.ts +19 -1
  105. package/dist/esm/wire/size-delimited.js +54 -16
  106. package/package.json +109 -30
  107. package/dist/cjs/codegenv2/enum.d.ts +0 -18
  108. package/dist/cjs/package.json +0 -1
  109. package/dist/cjs/reflect/scalar.d.ts +0 -21
  110. /package/dist/{cjs → commonjs}/clone.d.ts +0 -0
  111. /package/dist/{cjs → commonjs}/clone.js +0 -0
  112. /package/dist/{cjs → commonjs}/codegenv1/enum.d.ts +0 -0
  113. /package/dist/{cjs → commonjs}/codegenv1/enum.js +0 -0
  114. /package/dist/{cjs → commonjs}/codegenv1/extension.d.ts +0 -0
  115. /package/dist/{cjs → commonjs}/codegenv1/extension.js +0 -0
  116. /package/dist/{cjs → commonjs}/codegenv1/file.d.ts +0 -0
  117. /package/dist/{cjs → commonjs}/codegenv1/file.js +0 -0
  118. /package/dist/{cjs → commonjs}/codegenv1/index.d.ts +0 -0
  119. /package/dist/{cjs → commonjs}/codegenv1/index.js +0 -0
  120. /package/dist/{cjs → commonjs}/codegenv1/message.d.ts +0 -0
  121. /package/dist/{cjs → commonjs}/codegenv1/message.js +0 -0
  122. /package/dist/{cjs → commonjs}/codegenv1/service.d.ts +0 -0
  123. /package/dist/{cjs → commonjs}/codegenv1/service.js +0 -0
  124. /package/dist/{cjs → commonjs}/codegenv1/symbols.js +0 -0
  125. /package/dist/{cjs → commonjs/codegenv1}/types.js +0 -0
  126. /package/dist/{cjs → commonjs}/codegenv2/boot.d.ts +0 -0
  127. /package/dist/{cjs → commonjs}/codegenv2/boot.js +0 -0
  128. /package/dist/{cjs → commonjs}/codegenv2/embed.d.ts +0 -0
  129. /package/dist/{cjs → commonjs}/codegenv2/embed.js +0 -0
  130. /package/dist/{cjs → commonjs}/codegenv2/extension.d.ts +0 -0
  131. /package/dist/{cjs → commonjs}/codegenv2/extension.js +0 -0
  132. /package/dist/{cjs → commonjs}/codegenv2/file.d.ts +0 -0
  133. /package/dist/{cjs → commonjs}/codegenv2/file.js +0 -0
  134. /package/dist/{cjs → commonjs}/codegenv2/index.d.ts +0 -0
  135. /package/dist/{cjs → commonjs}/codegenv2/index.js +0 -0
  136. /package/dist/{cjs → commonjs}/codegenv2/message.d.ts +0 -0
  137. /package/dist/{cjs → commonjs}/codegenv2/message.js +0 -0
  138. /package/dist/{cjs → commonjs}/codegenv2/restore-json-names.d.ts +0 -0
  139. /package/dist/{cjs → commonjs}/codegenv2/restore-json-names.js +0 -0
  140. /package/dist/{cjs → commonjs}/codegenv2/scalar.d.ts +0 -0
  141. /package/dist/{cjs → commonjs}/codegenv2/scalar.js +0 -0
  142. /package/dist/{cjs → commonjs}/codegenv2/service.d.ts +0 -0
  143. /package/dist/{cjs → commonjs}/codegenv2/service.js +0 -0
  144. /package/dist/{cjs/json-value.js → commonjs/codegenv2/types.js} +0 -0
  145. /package/dist/{cjs → commonjs}/create.d.ts +0 -0
  146. /package/dist/{cjs → commonjs}/descriptors.js +0 -0
  147. /package/dist/{cjs → commonjs}/fields.d.ts +0 -0
  148. /package/dist/{cjs → commonjs}/fields.js +0 -0
  149. /package/dist/{cjs → commonjs}/is-message.d.ts +0 -0
  150. /package/dist/{cjs → commonjs}/is-message.js +0 -0
  151. /package/dist/{cjs → commonjs}/json-value.d.ts +0 -0
  152. /package/dist/{cjs → commonjs}/merge.d.ts +0 -0
  153. /package/dist/{cjs → commonjs}/merge.js +0 -0
  154. /package/dist/{cjs → commonjs}/proto-int64.d.ts +0 -0
  155. /package/dist/{cjs → commonjs}/reflect/error.d.ts +0 -0
  156. /package/dist/{cjs → commonjs}/reflect/error.js +0 -0
  157. /package/dist/{cjs → commonjs}/reflect/guard.d.ts +0 -0
  158. /package/dist/{cjs → commonjs}/reflect/guard.js +0 -0
  159. /package/dist/{cjs → commonjs}/reflect/index.d.ts +0 -0
  160. /package/dist/{cjs → commonjs}/reflect/index.js +0 -0
  161. /package/dist/{cjs → commonjs}/reflect/names.d.ts +0 -0
  162. /package/dist/{cjs → commonjs}/reflect/names.js +0 -0
  163. /package/dist/{cjs → commonjs}/reflect/nested-types.d.ts +0 -0
  164. /package/dist/{cjs → commonjs}/reflect/nested-types.js +0 -0
  165. /package/dist/{cjs → commonjs}/reflect/path.d.ts +0 -0
  166. /package/dist/{cjs → commonjs}/reflect/path.js +0 -0
  167. /package/dist/{cjs → commonjs}/reflect/reflect-check.d.ts +0 -0
  168. /package/dist/{cjs → commonjs}/reflect/reflect-types.d.ts +0 -0
  169. /package/dist/{cjs → commonjs}/reflect/reflect-types.js +0 -0
  170. /package/dist/{cjs → commonjs}/reflect/reflect.d.ts +0 -0
  171. /package/dist/{cjs → commonjs}/reflect/unsafe.d.ts +0 -0
  172. /package/dist/{cjs → commonjs}/registry.d.ts +0 -0
  173. /package/dist/{cjs → commonjs}/to-binary.d.ts +0 -0
  174. /package/dist/{cjs → commonjs}/to-json.d.ts +0 -0
  175. /package/dist/{cjs → commonjs}/wire/base64-encoding.d.ts +0 -0
  176. /package/dist/{cjs → commonjs}/wire/base64-encoding.js +0 -0
  177. /package/dist/{cjs → commonjs}/wire/index.d.ts +0 -0
  178. /package/dist/{cjs → commonjs}/wire/index.js +0 -0
  179. /package/dist/{cjs → commonjs}/wire/text-encoding.d.ts +0 -0
  180. /package/dist/{cjs → commonjs}/wire/text-encoding.js +0 -0
  181. /package/dist/{cjs → commonjs}/wire/text-format.d.ts +0 -0
  182. /package/dist/{cjs → commonjs}/wire/text-format.js +0 -0
  183. /package/dist/{cjs → commonjs}/wire/varint.d.ts +0 -0
  184. /package/dist/{cjs → commonjs}/wire/varint.js +0 -0
  185. /package/dist/{cjs → commonjs}/wkt/any.d.ts +0 -0
  186. /package/dist/{cjs → commonjs}/wkt/any.js +0 -0
  187. /package/dist/{cjs → commonjs}/wkt/duration.d.ts +0 -0
  188. /package/dist/{cjs → commonjs}/wkt/duration.js +0 -0
  189. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/any_pb.d.ts +0 -0
  190. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/any_pb.js +0 -0
  191. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/api_pb.d.ts +0 -0
  192. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/api_pb.js +0 -0
  193. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/compiler/plugin_pb.d.ts +0 -0
  194. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/compiler/plugin_pb.js +0 -0
  195. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/cpp_features_pb.d.ts +0 -0
  196. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/cpp_features_pb.js +0 -0
  197. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/descriptor_pb.d.ts +0 -0
  198. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/descriptor_pb.js +0 -0
  199. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/duration_pb.d.ts +0 -0
  200. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/duration_pb.js +0 -0
  201. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/empty_pb.d.ts +0 -0
  202. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/empty_pb.js +0 -0
  203. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/field_mask_pb.d.ts +0 -0
  204. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/field_mask_pb.js +0 -0
  205. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/go_features_pb.d.ts +0 -0
  206. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/go_features_pb.js +0 -0
  207. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/java_features_pb.d.ts +0 -0
  208. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/java_features_pb.js +0 -0
  209. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/source_context_pb.d.ts +0 -0
  210. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/source_context_pb.js +0 -0
  211. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/struct_pb.d.ts +0 -0
  212. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/struct_pb.js +0 -0
  213. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/timestamp_pb.d.ts +0 -0
  214. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/timestamp_pb.js +0 -0
  215. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/type_pb.d.ts +0 -0
  216. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/type_pb.js +0 -0
  217. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/wrappers_pb.d.ts +0 -0
  218. /package/dist/{cjs → commonjs}/wkt/gen/google/protobuf/wrappers_pb.js +0 -0
  219. /package/dist/{cjs → commonjs}/wkt/index.d.ts +0 -0
  220. /package/dist/{cjs → commonjs}/wkt/index.js +0 -0
  221. /package/dist/{cjs → commonjs}/wkt/timestamp.d.ts +0 -0
  222. /package/dist/{cjs → commonjs}/wkt/timestamp.js +0 -0
  223. /package/dist/{cjs → commonjs}/wkt/wrappers.d.ts +0 -0
  224. /package/dist/{cjs → commonjs}/wkt/wrappers.js +0 -0
@@ -0,0 +1,34 @@
1
+ import { type DescMessage } from "../descriptors.js";
2
+ import type { Registry } from "../registry.js";
3
+ import type { MessageShape } from "../types.js";
4
+ /**
5
+ * Options for serializing to the protobuf text format.
6
+ *
7
+ * The text format represents 64-bit integral types with BigInt and has no
8
+ * string fall-back: toText throws immediately when BigInt is unavailable.
9
+ */
10
+ export interface TextWriteOptions {
11
+ /**
12
+ * Print unknown fields?
13
+ *
14
+ * Disabled by default. This is a debugging aid only: unknown fields are
15
+ * printed by field number, and fromText rejects fields named by number, so
16
+ * output that includes them cannot be parsed back.
17
+ */
18
+ printUnknownFields: boolean;
19
+ /**
20
+ * The registry to resolve `google.protobuf.Any` and extensions. Without it,
21
+ * an Any is written as its raw `type_url`/`value` fields and extensions are
22
+ * omitted.
23
+ */
24
+ registry?: Registry | undefined;
25
+ }
26
+ /**
27
+ * Serialize a message to the protobuf text format.
28
+ *
29
+ * The output matches the default formatting of txtpbfmt: two-space indentation,
30
+ * one field per line, and a trailing newline.
31
+ *
32
+ * Requires BigInt: throws immediately if the environment does not support it.
33
+ */
34
+ export declare function toText<Desc extends DescMessage>(schema: Desc, message: MessageShape<Desc>, options?: Partial<TextWriteOptions>): string;
@@ -0,0 +1,358 @@
1
+ "use strict";
2
+ // Copyright 2021-2026 Buf Technologies, Inc.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.toText = toText;
17
+ const descriptors_js_1 = require("../descriptors.js");
18
+ const proto_int64_js_1 = require("../proto-int64.js");
19
+ const reflect_js_1 = require("../reflect/reflect.js");
20
+ const extensions_js_1 = require("../extensions.js");
21
+ const index_js_1 = require("../wire/index.js");
22
+ const index_js_2 = require("../wkt/index.js");
23
+ const is_group_like_js_1 = require("./is-group-like.js");
24
+ const writer_js_1 = require("./writer.js");
25
+ const textWriteDefaults = {
26
+ printUnknownFields: false,
27
+ };
28
+ function makeWriteOptions(options) {
29
+ return options ? Object.assign(Object.assign({}, textWriteDefaults), options) : textWriteDefaults;
30
+ }
31
+ // A bound on nested unknown-field rendering. The known-field tree is a finite,
32
+ // valid in-memory message and needs no limit, but printUnknownFields re-parses
33
+ // bytes and recurses (the length-delimited and group heuristics), so we cap
34
+ // that path as defense-in-depth.
35
+ const unknownFieldDepthLimit = 100;
36
+ /**
37
+ * Serialize a message to the protobuf text format.
38
+ *
39
+ * The output matches the default formatting of txtpbfmt: two-space indentation,
40
+ * one field per line, and a trailing newline.
41
+ *
42
+ * Requires BigInt: throws immediately if the environment does not support it.
43
+ */
44
+ function toText(schema, message, options) {
45
+ if (!proto_int64_js_1.protoInt64.supported) {
46
+ throw new Error("the protobuf text format requires BigInt, which is unavailable in this environment");
47
+ }
48
+ const writer = new writer_js_1.Writer();
49
+ writeMessage(writer, (0, reflect_js_1.reflect)(schema, message), makeWriteOptions(options));
50
+ return writer.toString();
51
+ }
52
+ /**
53
+ * Write the body of a message: regular fields in declaration order, then
54
+ * resolvable extensions sorted by full name, then unknown fields by number
55
+ * (only when printUnknownFields is enabled). For `google.protobuf.Any`, the
56
+ * expanded form replaces all of this.
57
+ */
58
+ function writeMessage(writer, msg, opts) {
59
+ var _a;
60
+ if (writeAny(writer, msg, opts)) {
61
+ return;
62
+ }
63
+ for (const field of msg.fields) {
64
+ // Unset fields are omitted, including unset required fields; like
65
+ // protobuf-go, we do not validate required fields when serializing.
66
+ if (msg.isSet(field)) {
67
+ writeField(writer, fieldTextName(field), field, msg, opts);
68
+ }
69
+ }
70
+ const extensionNumbers = writeExtensions(writer, msg, opts);
71
+ if (opts.printUnknownFields) {
72
+ for (const field of (_a = msg.getUnknown()) !== null && _a !== void 0 ? _a : []) {
73
+ if (!extensionNumbers.has(field.no)) {
74
+ writeUnknownField(writer, field, 0);
75
+ }
76
+ }
77
+ }
78
+ }
79
+ function writeField(writer, name, field, msg, opts) {
80
+ // Narrowing on fieldKind lets msg.get(field) return the precise reflect type
81
+ // for each case — ReflectMessage, ReflectList, ReflectMap, number, or a scalar
82
+ // value — so none of the branches need a cast.
83
+ switch (field.fieldKind) {
84
+ case "scalar":
85
+ writer.scalar(name, scalarToText(field.scalar, msg.get(field)));
86
+ break;
87
+ case "enum":
88
+ writer.scalar(name, enumToText(field.enum, msg.get(field)));
89
+ break;
90
+ case "message":
91
+ writeMessageValue(writer, name, msg.get(field), opts);
92
+ break;
93
+ case "list":
94
+ writeList(writer, name, field, msg.get(field), opts);
95
+ break;
96
+ case "map":
97
+ writeMap(writer, name, field, msg.get(field), opts);
98
+ break;
99
+ }
100
+ }
101
+ /**
102
+ * Write a message value as `name: { ... }`, or `name: {}` when it has no body.
103
+ * The body is rendered speculatively and rolled back if it turns out empty.
104
+ */
105
+ function writeMessageValue(writer, name, msg, opts) {
106
+ const mark = writer.mark();
107
+ writer.openMessage(name);
108
+ writeMessage(writer, msg, opts);
109
+ if (writer.writesSince(mark) === 1) {
110
+ // Only the opener was written, so the message is empty.
111
+ writer.reset(mark);
112
+ writer.emptyMessage(name);
113
+ }
114
+ else {
115
+ writer.end();
116
+ }
117
+ }
118
+ function writeList(writer, name, field, list, opts) {
119
+ switch (field.listKind) {
120
+ case "scalar":
121
+ for (const item of list) {
122
+ writer.scalar(name, scalarToText(field.scalar, item));
123
+ }
124
+ break;
125
+ case "enum":
126
+ for (const item of list) {
127
+ writer.scalar(name, enumToText(field.enum, item));
128
+ }
129
+ break;
130
+ case "message":
131
+ for (const item of list) {
132
+ writeMessageValue(writer, name, item, opts);
133
+ }
134
+ break;
135
+ }
136
+ }
137
+ function writeMap(writer, name, field, map, opts) {
138
+ // Map entries are emitted in iteration (insertion) order; unlike protobuf-go,
139
+ // we deliberately do not sort them.
140
+ for (const [key, value] of map) {
141
+ writer.openMessage(name);
142
+ writer.scalar("key", scalarToText(field.mapKey, key));
143
+ switch (field.mapKind) {
144
+ case "scalar":
145
+ writer.scalar("value", scalarToText(field.scalar, value));
146
+ break;
147
+ case "enum":
148
+ writer.scalar("value", enumToText(field.enum, value));
149
+ break;
150
+ case "message":
151
+ writeMessageValue(writer, "value", value, opts);
152
+ break;
153
+ }
154
+ writer.end();
155
+ }
156
+ }
157
+ /**
158
+ * Write `google.protobuf.Any` in its expanded form `[type.url]: { ... }`.
159
+ * Returns false (so the generic path writes `type_url`/`value` instead) when
160
+ * the message is not an Any, has no type URL, or the type cannot be resolved.
161
+ */
162
+ function writeAny(writer, msg, opts) {
163
+ if (msg.desc.typeName !== "google.protobuf.Any" ||
164
+ opts.registry === undefined) {
165
+ return false;
166
+ }
167
+ const any = msg.message;
168
+ if (any.typeUrl === "") {
169
+ return false;
170
+ }
171
+ const unpacked = (0, index_js_2.anyUnpack)(any, opts.registry);
172
+ if (unpacked === undefined) {
173
+ return false;
174
+ }
175
+ const desc = opts.registry.getMessage(unpacked.$typeName);
176
+ if (desc === undefined) {
177
+ return false;
178
+ }
179
+ // The bracketed name preserves the exact type URL, including a custom domain.
180
+ writeMessageValue(writer, "[" + any.typeUrl + "]", (0, reflect_js_1.reflect)(desc, unpacked), opts);
181
+ return true;
182
+ }
183
+ /**
184
+ * Write resolvable extensions, sorted by full name, and return their field
185
+ * numbers so writeMessage does not also emit them as raw unknown fields.
186
+ */
187
+ function writeExtensions(writer, msg, opts) {
188
+ const numbers = new Set();
189
+ const unknown = msg.getUnknown();
190
+ if (opts.registry === undefined || unknown === undefined) {
191
+ return numbers;
192
+ }
193
+ const extensions = [];
194
+ for (const { no } of unknown) {
195
+ if (numbers.has(no)) {
196
+ continue;
197
+ }
198
+ const extension = opts.registry.getExtensionFor(msg.desc, no);
199
+ if (extension !== undefined) {
200
+ numbers.add(no);
201
+ extensions.push(extension);
202
+ }
203
+ }
204
+ extensions.sort((a, b) => a.typeName < b.typeName ? -1 : a.typeName > b.typeName ? 1 : 0);
205
+ for (const extension of extensions) {
206
+ const value = (0, extensions_js_1.getExtension)(msg.message, extension);
207
+ const [container, field] = (0, extensions_js_1.createExtensionContainer)(extension, value);
208
+ writeField(writer, "[" + extension.typeName + "]", field, container, opts);
209
+ }
210
+ return numbers;
211
+ }
212
+ /**
213
+ * Write an unknown field by its field number, mirroring protobuf-go: varints as
214
+ * decimal, fixed-width values as hexadecimal, length-delimited data as a nested
215
+ * message when it parses cleanly as one and a quoted byte string otherwise, and
216
+ * groups recursively.
217
+ */
218
+ function writeUnknownField(writer, field, depth) {
219
+ const name = field.no.toString();
220
+ const reader = new index_js_1.BinaryReader(field.data);
221
+ switch (field.wireType) {
222
+ case index_js_1.WireType.Varint:
223
+ writer.scalar(name, reader.uint64().toString());
224
+ break;
225
+ case index_js_1.WireType.Bit32:
226
+ writer.scalar(name, "0x" + (reader.fixed32() >>> 0).toString(16).padStart(8, "0"));
227
+ break;
228
+ case index_js_1.WireType.Bit64:
229
+ writer.scalar(name, "0x" + BigInt(reader.fixed64()).toString(16).padStart(16, "0"));
230
+ break;
231
+ case index_js_1.WireType.LengthDelimited: {
232
+ const bytes = reader.bytes();
233
+ const nested = depth < unknownFieldDepthLimit ? parseUnknownMessage(bytes) : undefined;
234
+ if (nested === undefined) {
235
+ writer.scalar(name, (0, writer_js_1.quoteBytes)(bytes));
236
+ }
237
+ else {
238
+ writeUnknownGroup(writer, name, nested, depth);
239
+ }
240
+ break;
241
+ }
242
+ case index_js_1.WireType.StartGroup: {
243
+ const fields = [];
244
+ while (reader.pos < reader.len) {
245
+ const [no, wireType] = reader.tag();
246
+ if (wireType === index_js_1.WireType.EndGroup) {
247
+ break;
248
+ }
249
+ fields.push({ no, wireType, data: reader.skip(wireType, no) });
250
+ }
251
+ writeUnknownGroup(writer, name, fields, depth);
252
+ break;
253
+ }
254
+ }
255
+ }
256
+ function writeUnknownGroup(writer, name, fields, depth) {
257
+ if (fields.length === 0) {
258
+ writer.emptyMessage(name);
259
+ return;
260
+ }
261
+ writer.openMessage(name);
262
+ for (const field of fields) {
263
+ writeUnknownField(writer, field, depth + 1);
264
+ }
265
+ writer.end();
266
+ }
267
+ /**
268
+ * Try to interpret length-delimited bytes as a nested message. Returns its
269
+ * unknown fields if the bytes parse cleanly and completely, otherwise undefined
270
+ * (in which case the data is rendered as a quoted byte string).
271
+ */
272
+ function parseUnknownMessage(bytes) {
273
+ if (bytes.length === 0) {
274
+ return undefined;
275
+ }
276
+ const reader = new index_js_1.BinaryReader(bytes);
277
+ const fields = [];
278
+ try {
279
+ while (reader.pos < reader.len) {
280
+ const [no, wireType] = reader.tag();
281
+ if (no <= 0 || wireType === index_js_1.WireType.EndGroup) {
282
+ return undefined;
283
+ }
284
+ fields.push({ no, wireType, data: reader.skip(wireType, no) });
285
+ }
286
+ }
287
+ catch (_a) {
288
+ return undefined;
289
+ }
290
+ return reader.pos === reader.len ? fields : undefined;
291
+ }
292
+ /**
293
+ * The name a field is addressed by in the text format: a group-like (delimited)
294
+ * field uses its message type name, every other field its proto name.
295
+ */
296
+ function fieldTextName(field) {
297
+ return (0, is_group_like_js_1.isGroupLike)(field) ? field.message.name : field.name;
298
+ }
299
+ function scalarToText(type, value) {
300
+ switch (type) {
301
+ case descriptors_js_1.ScalarType.STRING:
302
+ return (0, writer_js_1.quoteString)(value);
303
+ case descriptors_js_1.ScalarType.BYTES:
304
+ return (0, writer_js_1.quoteBytes)(value);
305
+ case descriptors_js_1.ScalarType.BOOL:
306
+ return value === true ? "true" : "false";
307
+ case descriptors_js_1.ScalarType.FLOAT:
308
+ return floatToText(value, true);
309
+ case descriptors_js_1.ScalarType.DOUBLE:
310
+ return floatToText(value, false);
311
+ default:
312
+ // All integer types print as decimal with no prefix. 64-bit values are
313
+ // bigint; String() gives the decimal form for both bigint and number.
314
+ return String(value);
315
+ }
316
+ }
317
+ function enumToText(descEnum, value) {
318
+ // Emit the first-declared name for a value, so allow_alias enums match
319
+ // protobuf-go (the by-number record can resolve to a non-first alias). An
320
+ // unknown value prints as a decimal.
321
+ for (const v of descEnum.values) {
322
+ if (v.number === value) {
323
+ return v.name;
324
+ }
325
+ }
326
+ return value.toString();
327
+ }
328
+ function floatToText(value, single) {
329
+ // Round to 32-bit precision first so an overflow becomes inf (not the JS
330
+ // "Infinity") and the value is the true 32-bit value before we test it.
331
+ const n = single ? Math.fround(value) : value;
332
+ if (Number.isNaN(n)) {
333
+ return "nan";
334
+ }
335
+ if (n === Number.POSITIVE_INFINITY) {
336
+ return "inf";
337
+ }
338
+ if (n === Number.NEGATIVE_INFINITY) {
339
+ return "-inf";
340
+ }
341
+ if (Object.is(n, -0)) {
342
+ return "-0";
343
+ }
344
+ if (!single) {
345
+ // Number.prototype.toString already yields the shortest decimal that
346
+ // round-trips to the same 64-bit value.
347
+ return n.toString();
348
+ }
349
+ // For 32-bit floats, find the shortest decimal that round-trips to the same
350
+ // float32, mirroring strconv.AppendFloat(n, 'g', -1, 32) in protobuf-go.
351
+ for (let precision = 1; precision <= 9; precision++) {
352
+ const candidate = Number(n.toPrecision(precision));
353
+ if (Math.fround(candidate) === n) {
354
+ return candidate.toString();
355
+ }
356
+ }
357
+ return n.toString();
358
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * A position in the Writer's output, used to roll back speculative writes.
3
+ */
4
+ interface Mark {
5
+ readonly size: number;
6
+ readonly depth: number;
7
+ }
8
+ /**
9
+ * A writer for the protobuf text format.
10
+ *
11
+ * The Writer owns layout: indentation, line breaks, and braces. Its output
12
+ * matches the default formatting of txtpbfmt and the multi-line output of
13
+ * protobuf-go: two-space indentation, `name: value` with a single space after
14
+ * the colon, submessages as `name: {` with the body indented and `}` aligned
15
+ * under the field name, and a trailing newline. It never inserts the randomized
16
+ * extra spaces that protobuf-go adds to discourage parsing its output as
17
+ * canonical.
18
+ *
19
+ * Output accumulates into a single buffer of lines, so a deep tree costs no
20
+ * more than the bytes it prints. To decide between `name: {}` and an indented
21
+ * block, the caller renders the body, then rolls back with mark()/reset() if it
22
+ * turned out empty — an O(1) decision that needs no separate child buffer.
23
+ */
24
+ export declare class Writer {
25
+ private readonly chunks;
26
+ private depth;
27
+ /**
28
+ * Write a scalar field: `<indent>name: value` followed by a newline.
29
+ */
30
+ scalar(name: string, value: string): void;
31
+ /**
32
+ * Write an empty message field: `<indent>name: {}` followed by a newline.
33
+ */
34
+ emptyMessage(name: string): void;
35
+ /**
36
+ * Open a message field: `<indent>name: {` followed by a newline, then indent
37
+ * the body. Close it with end().
38
+ */
39
+ openMessage(name: string): void;
40
+ /**
41
+ * Close a message opened with openMessage(): outdent and write `<indent>}`
42
+ * followed by a newline.
43
+ */
44
+ end(): void;
45
+ /**
46
+ * Capture the current output position so it can be rolled back with reset().
47
+ */
48
+ mark(): Mark;
49
+ /**
50
+ * Roll back to a position captured with mark().
51
+ */
52
+ reset(mark: Mark): void;
53
+ /**
54
+ * The number of lines written since the given mark.
55
+ */
56
+ writesSince(mark: Mark): number;
57
+ toString(): string;
58
+ private indent;
59
+ }
60
+ /**
61
+ * Quote and escape a string field value as a double-quoted text format literal.
62
+ *
63
+ * Uses the single escaping decision in escapeCodePoint, so string fields, bytes
64
+ * fields, and unknown length-delimited rendering can never drift apart. Valid
65
+ * non-ASCII passes through as raw UTF-8; surrogates are never escaped.
66
+ */
67
+ export declare function quoteString(value: string): string;
68
+ /**
69
+ * Quote and escape a bytes field value as a double-quoted text format literal.
70
+ *
71
+ * Valid UTF-8 runs are emitted with escapeCodePoint (so they read identically
72
+ * to a string field); any byte that is not part of a valid UTF-8 sequence is
73
+ * emitted as `\xHH`, keeping the output plain ASCII that round-trips exactly.
74
+ */
75
+ export declare function quoteBytes(value: Uint8Array): string;
76
+ export {};
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ // Copyright 2021-2026 Buf Technologies, Inc.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.Writer = void 0;
17
+ exports.quoteString = quoteString;
18
+ exports.quoteBytes = quoteBytes;
19
+ const indentUnit = " ";
20
+ /**
21
+ * A writer for the protobuf text format.
22
+ *
23
+ * The Writer owns layout: indentation, line breaks, and braces. Its output
24
+ * matches the default formatting of txtpbfmt and the multi-line output of
25
+ * protobuf-go: two-space indentation, `name: value` with a single space after
26
+ * the colon, submessages as `name: {` with the body indented and `}` aligned
27
+ * under the field name, and a trailing newline. It never inserts the randomized
28
+ * extra spaces that protobuf-go adds to discourage parsing its output as
29
+ * canonical.
30
+ *
31
+ * Output accumulates into a single buffer of lines, so a deep tree costs no
32
+ * more than the bytes it prints. To decide between `name: {}` and an indented
33
+ * block, the caller renders the body, then rolls back with mark()/reset() if it
34
+ * turned out empty — an O(1) decision that needs no separate child buffer.
35
+ */
36
+ class Writer {
37
+ constructor() {
38
+ this.chunks = [];
39
+ this.depth = 0;
40
+ }
41
+ /**
42
+ * Write a scalar field: `<indent>name: value` followed by a newline.
43
+ */
44
+ scalar(name, value) {
45
+ this.chunks.push(this.indent() + name + ": " + value + "\n");
46
+ }
47
+ /**
48
+ * Write an empty message field: `<indent>name: {}` followed by a newline.
49
+ */
50
+ emptyMessage(name) {
51
+ this.chunks.push(this.indent() + name + ": {}\n");
52
+ }
53
+ /**
54
+ * Open a message field: `<indent>name: {` followed by a newline, then indent
55
+ * the body. Close it with end().
56
+ */
57
+ openMessage(name) {
58
+ this.chunks.push(this.indent() + name + ": {\n");
59
+ this.depth++;
60
+ }
61
+ /**
62
+ * Close a message opened with openMessage(): outdent and write `<indent>}`
63
+ * followed by a newline.
64
+ */
65
+ end() {
66
+ this.depth--;
67
+ this.chunks.push(this.indent() + "}\n");
68
+ }
69
+ /**
70
+ * Capture the current output position so it can be rolled back with reset().
71
+ */
72
+ mark() {
73
+ return { size: this.chunks.length, depth: this.depth };
74
+ }
75
+ /**
76
+ * Roll back to a position captured with mark().
77
+ */
78
+ reset(mark) {
79
+ this.chunks.length = mark.size;
80
+ this.depth = mark.depth;
81
+ }
82
+ /**
83
+ * The number of lines written since the given mark.
84
+ */
85
+ writesSince(mark) {
86
+ return this.chunks.length - mark.size;
87
+ }
88
+ toString() {
89
+ return this.chunks.join("");
90
+ }
91
+ indent() {
92
+ return indentUnit.repeat(this.depth);
93
+ }
94
+ }
95
+ exports.Writer = Writer;
96
+ /**
97
+ * Quote and escape a string field value as a double-quoted text format literal.
98
+ *
99
+ * Uses the single escaping decision in escapeCodePoint, so string fields, bytes
100
+ * fields, and unknown length-delimited rendering can never drift apart. Valid
101
+ * non-ASCII passes through as raw UTF-8; surrogates are never escaped.
102
+ */
103
+ function quoteString(value) {
104
+ var _a;
105
+ let out = '"';
106
+ for (const ch of value) {
107
+ out += (_a = escapeCodePoint(ch.codePointAt(0))) !== null && _a !== void 0 ? _a : ch;
108
+ }
109
+ return out + '"';
110
+ }
111
+ /**
112
+ * Quote and escape a bytes field value as a double-quoted text format literal.
113
+ *
114
+ * Valid UTF-8 runs are emitted with escapeCodePoint (so they read identically
115
+ * to a string field); any byte that is not part of a valid UTF-8 sequence is
116
+ * emitted as `\xHH`, keeping the output plain ASCII that round-trips exactly.
117
+ */
118
+ function quoteBytes(value) {
119
+ var _a;
120
+ let out = '"';
121
+ for (let i = 0; i < value.length;) {
122
+ const rune = decodeUtf8(value, i);
123
+ if (rune === undefined) {
124
+ out += "\\x" + hex2(value[i]);
125
+ i++;
126
+ continue;
127
+ }
128
+ out += (_a = escapeCodePoint(rune.code)) !== null && _a !== void 0 ? _a : String.fromCodePoint(rune.code);
129
+ i += rune.size;
130
+ }
131
+ return out + '"';
132
+ }
133
+ /**
134
+ * The single source of truth for escaping a code point in a text format string
135
+ * literal. Returns the escape sequence, or undefined when the code point may be
136
+ * emitted raw.
137
+ *
138
+ * Escapes the conventional sequences, all C0 controls and DEL as `\xHH`, and
139
+ * the C1 controls (U+0080–U+009F) as `\u00HH`. Surrogates and everything else
140
+ * pass through raw.
141
+ */
142
+ function escapeCodePoint(code) {
143
+ switch (code) {
144
+ case 0x5c:
145
+ return "\\\\";
146
+ case 0x22:
147
+ return '\\"';
148
+ case 0x0a:
149
+ return "\\n";
150
+ case 0x0d:
151
+ return "\\r";
152
+ case 0x09:
153
+ return "\\t";
154
+ }
155
+ if (code < 0x20 || code === 0x7f) {
156
+ return "\\x" + hex2(code);
157
+ }
158
+ if (code >= 0x80 && code <= 0x9f) {
159
+ return "\\u" + code.toString(16).padStart(4, "0");
160
+ }
161
+ return undefined;
162
+ }
163
+ /**
164
+ * Decode the UTF-8 sequence starting at `offset`, returning the code point and
165
+ * its byte length, or undefined if the bytes there are not valid UTF-8. We
166
+ * decode manually (rather than via TextDecoder) so an invalid byte can be
167
+ * pinpointed and escaped individually.
168
+ */
169
+ function decodeUtf8(bytes, offset) {
170
+ const b0 = bytes[offset];
171
+ if (b0 < 0x80) {
172
+ return { code: b0, size: 1 };
173
+ }
174
+ if (b0 < 0xc0) {
175
+ return undefined;
176
+ }
177
+ if (b0 < 0xe0) {
178
+ const b1 = bytes[offset + 1];
179
+ if (!isContinuation(b1)) {
180
+ return undefined;
181
+ }
182
+ const code = ((b0 & 0x1f) << 6) | (b1 & 0x3f);
183
+ return code < 0x80 ? undefined : { code, size: 2 };
184
+ }
185
+ if (b0 < 0xf0) {
186
+ const b1 = bytes[offset + 1];
187
+ const b2 = bytes[offset + 2];
188
+ if (!isContinuation(b1) || !isContinuation(b2)) {
189
+ return undefined;
190
+ }
191
+ const code = ((b0 & 0x0f) << 12) | ((b1 & 0x3f) << 6) | (b2 & 0x3f);
192
+ if (code < 0x800 || (code >= 0xd800 && code <= 0xdfff)) {
193
+ return undefined;
194
+ }
195
+ return { code, size: 3 };
196
+ }
197
+ if (b0 < 0xf8) {
198
+ const b1 = bytes[offset + 1];
199
+ const b2 = bytes[offset + 2];
200
+ const b3 = bytes[offset + 3];
201
+ if (!isContinuation(b1) || !isContinuation(b2) || !isContinuation(b3)) {
202
+ return undefined;
203
+ }
204
+ const code = ((b0 & 0x07) << 18) |
205
+ ((b1 & 0x3f) << 12) |
206
+ ((b2 & 0x3f) << 6) |
207
+ (b3 & 0x3f);
208
+ if (code < 0x10000 || code > 0x10ffff) {
209
+ return undefined;
210
+ }
211
+ return { code, size: 4 };
212
+ }
213
+ return undefined;
214
+ }
215
+ function isContinuation(byte) {
216
+ return byte !== undefined && (byte & 0xc0) === 0x80;
217
+ }
218
+ function hex2(value) {
219
+ return value.toString(16).padStart(2, "0");
220
+ }
@@ -71,6 +71,13 @@ export type UnknownField = {
71
71
  readonly wireType: WireType;
72
72
  readonly data: Uint8Array;
73
73
  };
74
+ /**
75
+ * An unknown enum is a value that's not in the set of values defined by an
76
+ * enum. Open Protobuf enums may
77
+ */
78
+ export type UnknownEnum = number & {
79
+ __unknown_enum: true;
80
+ };
74
81
  /**
75
82
  * Describes a streaming RPC declaration.
76
83
  */