@tabnas/proto 0.6.8 → 0.6.9
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.
- package/dist/proto.d.ts +1 -1
- package/dist/proto.js +1 -1
- package/dist/translate.js +155 -34
- package/dist/translate.js.map +1 -1
- package/package.json +1 -1
- package/src/proto.ts +1 -1
- package/src/translate.ts +155 -34
package/dist/proto.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ declare const Proto: {
|
|
|
12
12
|
};
|
|
13
13
|
declare function toDescriptor(cst: any, options?: Partial<ProtoOptions>): FileDescriptorProto;
|
|
14
14
|
declare function parse(src: string, options?: Partial<ProtoOptions>): FileDescriptorProto;
|
|
15
|
-
declare const VERSION = "0.6.
|
|
15
|
+
declare const VERSION = "0.6.9";
|
|
16
16
|
export { Proto, parse, toDescriptor, preflight, MAX_NESTING_DEPTH, VERSION };
|
|
17
17
|
export type { ProtoVersion };
|
|
18
18
|
export * from './descriptor';
|
package/dist/proto.js
CHANGED
|
@@ -88,7 +88,7 @@ function parse(src, options) {
|
|
|
88
88
|
// VERSION is this package's version. It MUST equal package.json "version":
|
|
89
89
|
// the release orchestrator rewrites both, and test/version.test.ts fails the
|
|
90
90
|
// build if they drift. Mirrors `const VERSION` in go/proto.go.
|
|
91
|
-
const VERSION = '0.6.
|
|
91
|
+
const VERSION = '0.6.9';
|
|
92
92
|
exports.VERSION = VERSION;
|
|
93
93
|
__exportStar(require("./descriptor"), exports);
|
|
94
94
|
var translate_1 = require("./translate");
|
package/dist/translate.js
CHANGED
|
@@ -43,8 +43,8 @@ const TRANSLATION = Object.freeze({
|
|
|
43
43
|
"A label the descriptor does not keep is not written as the file spelled it: an optional field of a proto2 file is written optional whether or not the file said so, and an optional field of a proto3 file that the descriptor does not mark proto3Optional, or of an edition file, is written with no label.",
|
|
44
44
|
"A map field is written as map<K, V> from the entry message the reader made for it, a group as a group block from its nested message, and a proto3 optional field's synthetic oneof is not written, since the reader makes each of them again.",
|
|
45
45
|
"A number is written as the descriptor holds it: a hexadecimal or octal field number, enum value or range bound is written in decimal, an exclusive range end as its last number or max, and a number the reader read as NaN (a digit separator, 1_0, which the lexer takes and JavaScript's Number refuses) as 0_0, which reads back as NaN.",
|
|
46
|
-
"A string literal is written between double quotes, or single quotes where its text holds a double quote and no single quote, its escapes as written, since the descriptor keeps a literal's text between its quotes; a text that holds both quotes is written between
|
|
47
|
-
"An option's value is one string to the descriptor whether the file wrote it as an identifier, a string literal or an aggregate in braces, so it is written as a string literal, as an aggregate only where
|
|
46
|
+
"A string literal is written between double quotes, or single quotes where its text holds a double quote and no single quote, its escapes as written, since the descriptor keeps a literal's text between its quotes; a text that holds both quotes is written between the quotes whose every occurrence in it is escaped; a backtick string holding a line break, which the descriptor keeps with its backticks and no quotes hold, is written as itself, but for a reserved name, which the reader takes only from a quoted literal or an identifier; and a text that nothing holds where it goes is refused: a control character that no literal or backtick string holds (a tab, a line break outside a backtick string, the other C0 controls), both quotes unescaped, or a backslash at its end that would escape the closing quote.",
|
|
47
|
+
"An option's value is one string to the descriptor whether the file wrote it as an identifier, a string literal or an aggregate in braces, so it is written as a string literal, as the backtick string it is where it is one, as an aggregate only where neither can hold its text (a line break, or both quotes unescaped), and as an identifier for the options descriptor.proto types as enums (optimize_for, ctype, jstype, retention, targets, idempotency_level and the features) when its text is made of identifier characters; protoc reads an enum-valued or message-valued option written as a literal as a string, and a quoted value of such an option that begins with a digit, which protoc refuses, does not read back; a value no literal or backtick string holds that is no aggregate's body, which no file's descriptor holds, is written in braces too and does not read back; and a value holding a control character that no literal, backtick string or aggregate holds is refused.",
|
|
48
48
|
"A default is written bare for a field that is not a string or bytes when its text is made of a constant's characters, and as a string literal otherwise; a quoted default of such a field whose text is made of those characters but spells no one constant, which protoc refuses, does not read back.",
|
|
49
49
|
"Reserved names are written as string literals in a proto2 or proto3 file and as identifiers in an edition file, a message's or an enum's reserved ranges in one reserved statement and its names in another, each extension range in an extensions statement of its own with its options, and each extension in an extend block of its own."
|
|
50
50
|
]
|
|
@@ -96,22 +96,30 @@ const TRANSLATION = Object.freeze({
|
|
|
96
96
|
; enum's inclusive end as it is, \`max\` for 2147483647.
|
|
97
97
|
; - A string from a string literal is kept as its text between the quotes,
|
|
98
98
|
; escapes as written, so it is written between double quotes, or single
|
|
99
|
-
; quotes where it holds a double quote and no single quote
|
|
100
|
-
;
|
|
101
|
-
;
|
|
102
|
-
;
|
|
103
|
-
;
|
|
99
|
+
; quotes where it holds a double quote and no single quote, and where it
|
|
100
|
+
; holds both, between the quotes it escapes (an escaped backslash, \`\\\\\`,
|
|
101
|
+
; escapes no quote after it). A backtick string, which the lexer reads
|
|
102
|
+
; across lines too, is kept as written, backticks and all, so one
|
|
103
|
+
; holding a line break, which no quotes hold, is written as itself. A
|
|
104
|
+
; reserved name is not: the reader takes one from a quoted literal or an
|
|
105
|
+
; identifier, and the words of a backtick string as names of their own.
|
|
106
|
+
; An option's value the reader read as an identifier, a quoted literal,
|
|
107
|
+
; a backtick string or an aggregate in braces is one string to the tree:
|
|
108
|
+
; it is written quoted, as the backtick string it is, as an aggregate
|
|
109
|
+
; (\`{...}\`) where neither can hold it (a line break, or both quotes
|
|
110
|
+
; unescaped), and as an identifier for the options descriptor.proto
|
|
104
111
|
; types as enums (\`optimize_for\`, \`ctype\`, \`jstype\`, \`retention\`,
|
|
105
112
|
; \`targets\`, \`idempotency_level\` and the features) where it is made of
|
|
106
|
-
; identifier characters
|
|
107
|
-
;
|
|
108
|
-
;
|
|
109
|
-
;
|
|
110
|
-
;
|
|
111
|
-
;
|
|
112
|
-
;
|
|
113
|
-
;
|
|
114
|
-
;
|
|
113
|
+
; identifier characters; a value a program made that no literal or
|
|
114
|
+
; backtick string holds and that is no aggregate's body is written in
|
|
115
|
+
; braces too, and the reader refuses it, since alchemy cannot parse an
|
|
116
|
+
; aggregate. A default is written bare for a field that is not a string
|
|
117
|
+
; or bytes, where it is made of the characters a constant is, and as a
|
|
118
|
+
; literal otherwise. alchemy cannot read a string a character at a time,
|
|
119
|
+
; so two texts a file can hold, each refused by protoc, do not read back:
|
|
120
|
+
; a quoted value of an enum-typed option that begins with a digit, and a
|
|
121
|
+
; quoted default of a field that is not a string whose text is a
|
|
122
|
+
; constant's characters spelling no one constant.
|
|
115
123
|
; - A field or enum number the reader could not read (JavaScript's Number
|
|
116
124
|
; of \`1_0\`, the lexer's digit separator) is NaN, null in JSON, and is
|
|
117
125
|
; written \`0_0\`, which reads back the same; an option's number that is
|
|
@@ -121,7 +129,12 @@ const TRANSLATION = Object.freeze({
|
|
|
121
129
|
; met: a root that is not an object, a syntax or an edition a \`.proto\`
|
|
122
130
|
; file cannot declare, a member a descriptor holds as a string that is not
|
|
123
131
|
; one, a field type that is no scalar's, an option's value that is not a
|
|
124
|
-
; string, a number or a boolean
|
|
132
|
+
; string, a number or a boolean, and a string that nothing a \`.proto\` file
|
|
133
|
+
; writes holds where the string goes: a control character (no literal
|
|
134
|
+
; holds one, a backtick string only a line break, and an option's
|
|
135
|
+
; aggregate only the tab and line breaks between its tokens), and outside
|
|
136
|
+
; an option's value, both quotes unescaped or a backslash at the end,
|
|
137
|
+
; which would escape the closing quote.
|
|
125
138
|
;
|
|
126
139
|
; The tree is materialized whole before a line is written, since the
|
|
127
140
|
; syntax comes first in the file and last in the tree, and a field's place
|
|
@@ -255,23 +268,123 @@ def proto-ident-chars [[48 57] [65 90] [95 95] [97 122]]
|
|
|
255
268
|
; The characters of a bare constant: a number, a signed one, an identifier.
|
|
256
269
|
def proto-bare-chars [[43 43] [45 46] [48 57] [65 90] [95 95] [97 122]]
|
|
257
270
|
|
|
258
|
-
;
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
271
|
+
; The characters a backtick string holds, as the lexer reads one: the
|
|
272
|
+
; line feed and the carriage return that carry it across lines, and none
|
|
273
|
+
; of the other controls.
|
|
274
|
+
def proto-in-backtick [[10 10] [13 13] [32 1114111]]
|
|
275
|
+
|
|
276
|
+
; The characters an aggregate holds: its tokens, and the tab, the line
|
|
277
|
+
; feed and the carriage return as the whitespace between them.
|
|
278
|
+
def proto-in-aggregate [[9 10] [13 13] [32 1114111]]
|
|
279
|
+
|
|
280
|
+
; Whether s is a backtick string's text as the reader keeps it, the
|
|
281
|
+
; backticks and all: the lexer reads a backtick string across lines too,
|
|
282
|
+
; a backslash escaping the character after it, and the reader keeps a
|
|
283
|
+
; constant that is not quoted as it was written. So s has a backtick at
|
|
284
|
+
; each end and none unescaped between them, no backslash before the last
|
|
285
|
+
; that would escape it, and no control but a line break.
|
|
286
|
+
def proto-backtick [s]
|
|
287
|
+
let [parts (split "\`" s)]
|
|
288
|
+
match (proto-less 2 (count parts))
|
|
289
|
+
case false false
|
|
290
|
+
case true
|
|
291
|
+
match (match (proto-at parts 0) (case "" (match (top parts) (case "" true) (case _ false))) (case _ false))
|
|
292
|
+
case false false
|
|
293
|
+
case true
|
|
294
|
+
match (chars-within proto-in-backtick s)
|
|
295
|
+
case false false
|
|
296
|
+
case true (proto-escaped-inside "\`" (proto-after "\`" (string-join "\`" (pop parts))))
|
|
297
|
+
|
|
298
|
+
; Whether text could stand between quotes q as the lexer reads them: every
|
|
299
|
+
; q in it escaped, and no backslash at its end to escape the closing one.
|
|
300
|
+
def proto-escaped-inside [q text]
|
|
301
|
+
match (proto-quotes-escaped q text)
|
|
302
|
+
case false false
|
|
303
|
+
case true
|
|
304
|
+
match (proto-open-escape text)
|
|
305
|
+
case true false
|
|
306
|
+
case false true
|
|
307
|
+
|
|
308
|
+
; Whether every quote q in s is escaped, as in the text of a literal
|
|
309
|
+
; between those quotes. The lexer reads an escape as a backslash and the
|
|
310
|
+
; character after it, so an escaped backslash (\`\\\\\`) escapes nothing
|
|
311
|
+
; after it: s is read in the runs between its escaped backslashes, found
|
|
312
|
+
; from the front as the lexer finds them, and in a run a quote is escaped
|
|
313
|
+
; where a backslash comes right before it.
|
|
314
|
+
def proto-quotes-escaped [q s]
|
|
315
|
+
match (count (filter (fn [run] (proto-bare-quote q run)) (split "\\\\\\\\" s)))
|
|
316
|
+
case 0 true
|
|
317
|
+
case _ false
|
|
318
|
+
|
|
319
|
+
; Whether a run of a literal's text that holds no escaped backslash holds
|
|
320
|
+
; the quote q with no backslash right before it.
|
|
321
|
+
def proto-bare-quote [q run]
|
|
322
|
+
match (count (filter (fn [piece] (proto-less 1 (count (split q piece)))) (split (string-join "" ["\\\\" q]) run)))
|
|
323
|
+
case 0 false
|
|
324
|
+
case _ true
|
|
325
|
+
|
|
326
|
+
; Whether s ends with a backslash that escapes nothing in it, which would
|
|
327
|
+
; escape the quote written after it: its last run between escaped
|
|
328
|
+
; backslashes ends with one.
|
|
329
|
+
def proto-open-escape [s]
|
|
330
|
+
let [pieces (split "\\\\" (top (split "\\\\\\\\" s)))]
|
|
331
|
+
match (count pieces)
|
|
332
|
+
case 1 false
|
|
333
|
+
case _
|
|
334
|
+
match (top pieces)
|
|
335
|
+
case "" true
|
|
336
|
+
case _ false
|
|
266
337
|
|
|
267
|
-
;
|
|
338
|
+
; A literal's text between quotes that hold it, or "" where none do:
|
|
339
|
+
; double quotes where it holds no double quote, single quotes where it
|
|
340
|
+
; holds no single quote, and where it holds both, the quotes it escapes.
|
|
341
|
+
; No quotes hold a control character, both quotes unescaped, or a
|
|
342
|
+
; backslash at the end that would escape the closing quote.
|
|
343
|
+
def proto-quoted [s]
|
|
344
|
+
match (chars-within [[32 1114111]] s)
|
|
345
|
+
case false ""
|
|
346
|
+
case true
|
|
347
|
+
match (proto-open-escape s)
|
|
348
|
+
case true ""
|
|
349
|
+
case false
|
|
350
|
+
match (chars-within proto-no-dq s)
|
|
351
|
+
case true (string-join "" ["\\"" s "\\""])
|
|
352
|
+
case false
|
|
353
|
+
match (chars-within proto-no-sq s)
|
|
354
|
+
case true (string-join "" ["'" s "'"])
|
|
355
|
+
case false
|
|
356
|
+
match (proto-quotes-escaped "\\"" s)
|
|
357
|
+
case true (string-join "" ["\\"" s "\\""])
|
|
358
|
+
case false
|
|
359
|
+
match (proto-quotes-escaped "'" s)
|
|
360
|
+
case true (string-join "" ["'" s "'"])
|
|
361
|
+
case false ""
|
|
362
|
+
|
|
363
|
+
; A string literal whose text is s, as written: between quotes, or as the
|
|
364
|
+
; backtick string it is, which holds a line break no quotes hold. A text
|
|
365
|
+
; neither holds fails.
|
|
366
|
+
def proto-literal [s]
|
|
367
|
+
match (proto-quoted s)
|
|
368
|
+
case ""
|
|
369
|
+
match (proto-backtick s)
|
|
370
|
+
case true s
|
|
371
|
+
case false (fail :unrepresentable "a string holds what no literal or backtick string holds: a control character, both quotes unescaped, or a backslash that would escape the closing quote")
|
|
372
|
+
case q q
|
|
373
|
+
|
|
374
|
+
; An option's string: a literal, the backtick string it is, or the
|
|
375
|
+
; aggregate it is, whose braces hold what no literal holds (a line break,
|
|
376
|
+
; or both quotes unescaped). A control that no literal, backtick string
|
|
377
|
+
; or aggregate holds fails.
|
|
268
378
|
def proto-option-string [s]
|
|
269
|
-
match (
|
|
270
|
-
case
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
case
|
|
274
|
-
|
|
379
|
+
match (proto-quoted s)
|
|
380
|
+
case ""
|
|
381
|
+
match (proto-backtick s)
|
|
382
|
+
case true s
|
|
383
|
+
case false
|
|
384
|
+
match (chars-within proto-in-aggregate s)
|
|
385
|
+
case true (string-join "" ["{" s "}"])
|
|
386
|
+
case false (fail :unrepresentable "an option's value holds a control character that no literal, backtick string or aggregate holds")
|
|
387
|
+
case q q
|
|
275
388
|
|
|
276
389
|
; The options descriptor.proto types as enums, whose values are identifiers.
|
|
277
390
|
def proto-enum-option [k]
|
|
@@ -523,8 +636,16 @@ def proto-reserved-name [syntax n]
|
|
|
523
636
|
case "editions"
|
|
524
637
|
match (proto-identifier n)
|
|
525
638
|
case true n
|
|
526
|
-
case false (proto-literal n)
|
|
527
|
-
case _ (proto-literal n)
|
|
639
|
+
case false (proto-name-literal n)
|
|
640
|
+
case _ (proto-name-literal n)
|
|
641
|
+
|
|
642
|
+
; A reserved name between quotes. The reader takes a reserved name from a
|
|
643
|
+
; quoted literal or an identifier, and reads the words of a backtick
|
|
644
|
+
; string as names of their own, so a name no quotes hold fails.
|
|
645
|
+
def proto-name-literal [n]
|
|
646
|
+
match (proto-quoted n)
|
|
647
|
+
case "" (fail :unrepresentable "a reserved name holds what no quotes hold: a control character, both quotes unescaped, or a backslash that would escape the closing quote")
|
|
648
|
+
case q q
|
|
528
649
|
|
|
529
650
|
def proto-reserved-names [syntax indent names]
|
|
530
651
|
match (count names)
|
package/dist/translate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":";AAAA,2EAA2E;;
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":";AAAA,2EAA2E;;QA2pCzE,SAAS;AA1oCX,MAAM,WAAW,GAAqB,MAAM,CAAC,MAAM,CAAC;IAClD,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CX;IACC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAilCxD,EAAE,CAAC;CACH,CAAC,CAAA;AAEF,SAAS,SAAS;IAChB,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tabnas/proto",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"description": "Parse Protocol Buffers .proto IDL (proto2, proto3, edition 2023/2024) into FileDescriptorProto-shaped JSON, using the Tabnas parser and an ABNF grammar.",
|
|
5
5
|
"main": "dist/proto.js",
|
|
6
6
|
"type": "commonjs",
|
package/src/proto.ts
CHANGED
|
@@ -89,7 +89,7 @@ function parse(src: string, options?: Partial<ProtoOptions>): FileDescriptorProt
|
|
|
89
89
|
// VERSION is this package's version. It MUST equal package.json "version":
|
|
90
90
|
// the release orchestrator rewrites both, and test/version.test.ts fails the
|
|
91
91
|
// build if they drift. Mirrors `const VERSION` in go/proto.go.
|
|
92
|
-
const VERSION = '0.6.
|
|
92
|
+
const VERSION = '0.6.9'
|
|
93
93
|
|
|
94
94
|
export { Proto, parse, toDescriptor, preflight, MAX_NESTING_DEPTH, VERSION }
|
|
95
95
|
export type { ProtoVersion }
|
package/src/translate.ts
CHANGED
|
@@ -56,8 +56,8 @@ const TRANSLATION: TranslationParts = Object.freeze({
|
|
|
56
56
|
"A label the descriptor does not keep is not written as the file spelled it: an optional field of a proto2 file is written optional whether or not the file said so, and an optional field of a proto3 file that the descriptor does not mark proto3Optional, or of an edition file, is written with no label.",
|
|
57
57
|
"A map field is written as map<K, V> from the entry message the reader made for it, a group as a group block from its nested message, and a proto3 optional field's synthetic oneof is not written, since the reader makes each of them again.",
|
|
58
58
|
"A number is written as the descriptor holds it: a hexadecimal or octal field number, enum value or range bound is written in decimal, an exclusive range end as its last number or max, and a number the reader read as NaN (a digit separator, 1_0, which the lexer takes and JavaScript's Number refuses) as 0_0, which reads back as NaN.",
|
|
59
|
-
"A string literal is written between double quotes, or single quotes where its text holds a double quote and no single quote, its escapes as written, since the descriptor keeps a literal's text between its quotes; a text that holds both quotes is written between
|
|
60
|
-
"An option's value is one string to the descriptor whether the file wrote it as an identifier, a string literal or an aggregate in braces, so it is written as a string literal, as an aggregate only where
|
|
59
|
+
"A string literal is written between double quotes, or single quotes where its text holds a double quote and no single quote, its escapes as written, since the descriptor keeps a literal's text between its quotes; a text that holds both quotes is written between the quotes whose every occurrence in it is escaped; a backtick string holding a line break, which the descriptor keeps with its backticks and no quotes hold, is written as itself, but for a reserved name, which the reader takes only from a quoted literal or an identifier; and a text that nothing holds where it goes is refused: a control character that no literal or backtick string holds (a tab, a line break outside a backtick string, the other C0 controls), both quotes unescaped, or a backslash at its end that would escape the closing quote.",
|
|
60
|
+
"An option's value is one string to the descriptor whether the file wrote it as an identifier, a string literal or an aggregate in braces, so it is written as a string literal, as the backtick string it is where it is one, as an aggregate only where neither can hold its text (a line break, or both quotes unescaped), and as an identifier for the options descriptor.proto types as enums (optimize_for, ctype, jstype, retention, targets, idempotency_level and the features) when its text is made of identifier characters; protoc reads an enum-valued or message-valued option written as a literal as a string, and a quoted value of such an option that begins with a digit, which protoc refuses, does not read back; a value no literal or backtick string holds that is no aggregate's body, which no file's descriptor holds, is written in braces too and does not read back; and a value holding a control character that no literal, backtick string or aggregate holds is refused.",
|
|
61
61
|
"A default is written bare for a field that is not a string or bytes when its text is made of a constant's characters, and as a string literal otherwise; a quoted default of such a field whose text is made of those characters but spells no one constant, which protoc refuses, does not read back.",
|
|
62
62
|
"Reserved names are written as string literals in a proto2 or proto3 file and as identifiers in an edition file, a message's or an enum's reserved ranges in one reserved statement and its names in another, each extension range in an extensions statement of its own with its options, and each extension in an extend block of its own."
|
|
63
63
|
]
|
|
@@ -109,22 +109,30 @@ const TRANSLATION: TranslationParts = Object.freeze({
|
|
|
109
109
|
; enum's inclusive end as it is, \`max\` for 2147483647.
|
|
110
110
|
; - A string from a string literal is kept as its text between the quotes,
|
|
111
111
|
; escapes as written, so it is written between double quotes, or single
|
|
112
|
-
; quotes where it holds a double quote and no single quote
|
|
113
|
-
;
|
|
114
|
-
;
|
|
115
|
-
;
|
|
116
|
-
;
|
|
112
|
+
; quotes where it holds a double quote and no single quote, and where it
|
|
113
|
+
; holds both, between the quotes it escapes (an escaped backslash, \`\\\\\`,
|
|
114
|
+
; escapes no quote after it). A backtick string, which the lexer reads
|
|
115
|
+
; across lines too, is kept as written, backticks and all, so one
|
|
116
|
+
; holding a line break, which no quotes hold, is written as itself. A
|
|
117
|
+
; reserved name is not: the reader takes one from a quoted literal or an
|
|
118
|
+
; identifier, and the words of a backtick string as names of their own.
|
|
119
|
+
; An option's value the reader read as an identifier, a quoted literal,
|
|
120
|
+
; a backtick string or an aggregate in braces is one string to the tree:
|
|
121
|
+
; it is written quoted, as the backtick string it is, as an aggregate
|
|
122
|
+
; (\`{...}\`) where neither can hold it (a line break, or both quotes
|
|
123
|
+
; unescaped), and as an identifier for the options descriptor.proto
|
|
117
124
|
; types as enums (\`optimize_for\`, \`ctype\`, \`jstype\`, \`retention\`,
|
|
118
125
|
; \`targets\`, \`idempotency_level\` and the features) where it is made of
|
|
119
|
-
; identifier characters
|
|
120
|
-
;
|
|
121
|
-
;
|
|
122
|
-
;
|
|
123
|
-
;
|
|
124
|
-
;
|
|
125
|
-
;
|
|
126
|
-
;
|
|
127
|
-
;
|
|
126
|
+
; identifier characters; a value a program made that no literal or
|
|
127
|
+
; backtick string holds and that is no aggregate's body is written in
|
|
128
|
+
; braces too, and the reader refuses it, since alchemy cannot parse an
|
|
129
|
+
; aggregate. A default is written bare for a field that is not a string
|
|
130
|
+
; or bytes, where it is made of the characters a constant is, and as a
|
|
131
|
+
; literal otherwise. alchemy cannot read a string a character at a time,
|
|
132
|
+
; so two texts a file can hold, each refused by protoc, do not read back:
|
|
133
|
+
; a quoted value of an enum-typed option that begins with a digit, and a
|
|
134
|
+
; quoted default of a field that is not a string whose text is a
|
|
135
|
+
; constant's characters spelling no one constant.
|
|
128
136
|
; - A field or enum number the reader could not read (JavaScript's Number
|
|
129
137
|
; of \`1_0\`, the lexer's digit separator) is NaN, null in JSON, and is
|
|
130
138
|
; written \`0_0\`, which reads back the same; an option's number that is
|
|
@@ -134,7 +142,12 @@ const TRANSLATION: TranslationParts = Object.freeze({
|
|
|
134
142
|
; met: a root that is not an object, a syntax or an edition a \`.proto\`
|
|
135
143
|
; file cannot declare, a member a descriptor holds as a string that is not
|
|
136
144
|
; one, a field type that is no scalar's, an option's value that is not a
|
|
137
|
-
; string, a number or a boolean
|
|
145
|
+
; string, a number or a boolean, and a string that nothing a \`.proto\` file
|
|
146
|
+
; writes holds where the string goes: a control character (no literal
|
|
147
|
+
; holds one, a backtick string only a line break, and an option's
|
|
148
|
+
; aggregate only the tab and line breaks between its tokens), and outside
|
|
149
|
+
; an option's value, both quotes unescaped or a backslash at the end,
|
|
150
|
+
; which would escape the closing quote.
|
|
138
151
|
;
|
|
139
152
|
; The tree is materialized whole before a line is written, since the
|
|
140
153
|
; syntax comes first in the file and last in the tree, and a field's place
|
|
@@ -268,23 +281,123 @@ def proto-ident-chars [[48 57] [65 90] [95 95] [97 122]]
|
|
|
268
281
|
; The characters of a bare constant: a number, a signed one, an identifier.
|
|
269
282
|
def proto-bare-chars [[43 43] [45 46] [48 57] [65 90] [95 95] [97 122]]
|
|
270
283
|
|
|
271
|
-
;
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
284
|
+
; The characters a backtick string holds, as the lexer reads one: the
|
|
285
|
+
; line feed and the carriage return that carry it across lines, and none
|
|
286
|
+
; of the other controls.
|
|
287
|
+
def proto-in-backtick [[10 10] [13 13] [32 1114111]]
|
|
288
|
+
|
|
289
|
+
; The characters an aggregate holds: its tokens, and the tab, the line
|
|
290
|
+
; feed and the carriage return as the whitespace between them.
|
|
291
|
+
def proto-in-aggregate [[9 10] [13 13] [32 1114111]]
|
|
292
|
+
|
|
293
|
+
; Whether s is a backtick string's text as the reader keeps it, the
|
|
294
|
+
; backticks and all: the lexer reads a backtick string across lines too,
|
|
295
|
+
; a backslash escaping the character after it, and the reader keeps a
|
|
296
|
+
; constant that is not quoted as it was written. So s has a backtick at
|
|
297
|
+
; each end and none unescaped between them, no backslash before the last
|
|
298
|
+
; that would escape it, and no control but a line break.
|
|
299
|
+
def proto-backtick [s]
|
|
300
|
+
let [parts (split "\`" s)]
|
|
301
|
+
match (proto-less 2 (count parts))
|
|
302
|
+
case false false
|
|
303
|
+
case true
|
|
304
|
+
match (match (proto-at parts 0) (case "" (match (top parts) (case "" true) (case _ false))) (case _ false))
|
|
305
|
+
case false false
|
|
306
|
+
case true
|
|
307
|
+
match (chars-within proto-in-backtick s)
|
|
308
|
+
case false false
|
|
309
|
+
case true (proto-escaped-inside "\`" (proto-after "\`" (string-join "\`" (pop parts))))
|
|
310
|
+
|
|
311
|
+
; Whether text could stand between quotes q as the lexer reads them: every
|
|
312
|
+
; q in it escaped, and no backslash at its end to escape the closing one.
|
|
313
|
+
def proto-escaped-inside [q text]
|
|
314
|
+
match (proto-quotes-escaped q text)
|
|
315
|
+
case false false
|
|
316
|
+
case true
|
|
317
|
+
match (proto-open-escape text)
|
|
318
|
+
case true false
|
|
319
|
+
case false true
|
|
320
|
+
|
|
321
|
+
; Whether every quote q in s is escaped, as in the text of a literal
|
|
322
|
+
; between those quotes. The lexer reads an escape as a backslash and the
|
|
323
|
+
; character after it, so an escaped backslash (\`\\\\\`) escapes nothing
|
|
324
|
+
; after it: s is read in the runs between its escaped backslashes, found
|
|
325
|
+
; from the front as the lexer finds them, and in a run a quote is escaped
|
|
326
|
+
; where a backslash comes right before it.
|
|
327
|
+
def proto-quotes-escaped [q s]
|
|
328
|
+
match (count (filter (fn [run] (proto-bare-quote q run)) (split "\\\\\\\\" s)))
|
|
329
|
+
case 0 true
|
|
330
|
+
case _ false
|
|
331
|
+
|
|
332
|
+
; Whether a run of a literal's text that holds no escaped backslash holds
|
|
333
|
+
; the quote q with no backslash right before it.
|
|
334
|
+
def proto-bare-quote [q run]
|
|
335
|
+
match (count (filter (fn [piece] (proto-less 1 (count (split q piece)))) (split (string-join "" ["\\\\" q]) run)))
|
|
336
|
+
case 0 false
|
|
337
|
+
case _ true
|
|
338
|
+
|
|
339
|
+
; Whether s ends with a backslash that escapes nothing in it, which would
|
|
340
|
+
; escape the quote written after it: its last run between escaped
|
|
341
|
+
; backslashes ends with one.
|
|
342
|
+
def proto-open-escape [s]
|
|
343
|
+
let [pieces (split "\\\\" (top (split "\\\\\\\\" s)))]
|
|
344
|
+
match (count pieces)
|
|
345
|
+
case 1 false
|
|
346
|
+
case _
|
|
347
|
+
match (top pieces)
|
|
348
|
+
case "" true
|
|
349
|
+
case _ false
|
|
279
350
|
|
|
280
|
-
;
|
|
351
|
+
; A literal's text between quotes that hold it, or "" where none do:
|
|
352
|
+
; double quotes where it holds no double quote, single quotes where it
|
|
353
|
+
; holds no single quote, and where it holds both, the quotes it escapes.
|
|
354
|
+
; No quotes hold a control character, both quotes unescaped, or a
|
|
355
|
+
; backslash at the end that would escape the closing quote.
|
|
356
|
+
def proto-quoted [s]
|
|
357
|
+
match (chars-within [[32 1114111]] s)
|
|
358
|
+
case false ""
|
|
359
|
+
case true
|
|
360
|
+
match (proto-open-escape s)
|
|
361
|
+
case true ""
|
|
362
|
+
case false
|
|
363
|
+
match (chars-within proto-no-dq s)
|
|
364
|
+
case true (string-join "" ["\\"" s "\\""])
|
|
365
|
+
case false
|
|
366
|
+
match (chars-within proto-no-sq s)
|
|
367
|
+
case true (string-join "" ["'" s "'"])
|
|
368
|
+
case false
|
|
369
|
+
match (proto-quotes-escaped "\\"" s)
|
|
370
|
+
case true (string-join "" ["\\"" s "\\""])
|
|
371
|
+
case false
|
|
372
|
+
match (proto-quotes-escaped "'" s)
|
|
373
|
+
case true (string-join "" ["'" s "'"])
|
|
374
|
+
case false ""
|
|
375
|
+
|
|
376
|
+
; A string literal whose text is s, as written: between quotes, or as the
|
|
377
|
+
; backtick string it is, which holds a line break no quotes hold. A text
|
|
378
|
+
; neither holds fails.
|
|
379
|
+
def proto-literal [s]
|
|
380
|
+
match (proto-quoted s)
|
|
381
|
+
case ""
|
|
382
|
+
match (proto-backtick s)
|
|
383
|
+
case true s
|
|
384
|
+
case false (fail :unrepresentable "a string holds what no literal or backtick string holds: a control character, both quotes unescaped, or a backslash that would escape the closing quote")
|
|
385
|
+
case q q
|
|
386
|
+
|
|
387
|
+
; An option's string: a literal, the backtick string it is, or the
|
|
388
|
+
; aggregate it is, whose braces hold what no literal holds (a line break,
|
|
389
|
+
; or both quotes unescaped). A control that no literal, backtick string
|
|
390
|
+
; or aggregate holds fails.
|
|
281
391
|
def proto-option-string [s]
|
|
282
|
-
match (
|
|
283
|
-
case
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
case
|
|
287
|
-
|
|
392
|
+
match (proto-quoted s)
|
|
393
|
+
case ""
|
|
394
|
+
match (proto-backtick s)
|
|
395
|
+
case true s
|
|
396
|
+
case false
|
|
397
|
+
match (chars-within proto-in-aggregate s)
|
|
398
|
+
case true (string-join "" ["{" s "}"])
|
|
399
|
+
case false (fail :unrepresentable "an option's value holds a control character that no literal, backtick string or aggregate holds")
|
|
400
|
+
case q q
|
|
288
401
|
|
|
289
402
|
; The options descriptor.proto types as enums, whose values are identifiers.
|
|
290
403
|
def proto-enum-option [k]
|
|
@@ -536,8 +649,16 @@ def proto-reserved-name [syntax n]
|
|
|
536
649
|
case "editions"
|
|
537
650
|
match (proto-identifier n)
|
|
538
651
|
case true n
|
|
539
|
-
case false (proto-literal n)
|
|
540
|
-
case _ (proto-literal n)
|
|
652
|
+
case false (proto-name-literal n)
|
|
653
|
+
case _ (proto-name-literal n)
|
|
654
|
+
|
|
655
|
+
; A reserved name between quotes. The reader takes a reserved name from a
|
|
656
|
+
; quoted literal or an identifier, and reads the words of a backtick
|
|
657
|
+
; string as names of their own, so a name no quotes hold fails.
|
|
658
|
+
def proto-name-literal [n]
|
|
659
|
+
match (proto-quoted n)
|
|
660
|
+
case "" (fail :unrepresentable "a reserved name holds what no quotes hold: a control character, both quotes unescaped, or a backslash that would escape the closing quote")
|
|
661
|
+
case q q
|
|
541
662
|
|
|
542
663
|
def proto-reserved-names [syntax indent names]
|
|
543
664
|
match (count names)
|