Skip to content

Commit

Permalink
Support proto files with adjacent string literals (#922)
Browse files Browse the repository at this point in the history
  • Loading branch information
AriehSchneier committed Jun 4, 2024
1 parent 6dc9f55 commit f5435c3
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 7 deletions.
Binary file modified internal/bundles/assets/import_proto_cli.arraiz
Binary file not shown.
19 changes: 16 additions & 3 deletions pkg/importer/proto/proto_parser.arrai
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ floatLit -> /{\d+(?:\.\d+?)? (?:e[-+]?\d+)? | \. \d+ (?:e[-+]?\d+)? | inf

boolLit -> /{true | false};

strLit -> ('"' [^"]*:'""' '"' | "'" [^']*:"''" "'"); //';
strLit -> ('"' s=([^"]*:'""') '"' | "'" s=([^']*:"''") "'"):\s; //';

object -> "{" (c* objectField comma? c*)* "}";
objectField -> objectKey ":"? objectValue;
Expand Down Expand Up @@ -133,9 +133,22 @@ let evalType = \currentPackage \parsed

let evalLabel = \parsed parsed.'' rank (:.@) ;

let concatStrLit = \strLit
//seq.concat(//seq.concat(
(strLit.s >> .'') => \i (
@:i.@,
@item: i.@item >> \v
let s=(v rank (:.@));
cond strLit.@choice(i.@) {
0: cond s {'""':'"', _:s},
1: cond s {"''":"'", _:s},
}
)
));

let rec evalConstant = \parsed
cond parsed {
(:strLit, ...): (s: //re.compile(`\\\\`).sub(`\`, strLit.''(1) rank (:.@))),
(:strLit, ...): (s: //re.compile(`\\\\`).sub(`\`, concatStrLit(strLit))),
(:intLit, ...): evalConstant(intLit),
(:decimalLit, ...): (d: //eval.value(decimalLit.'' rank (:.@))),
(:octalLit, ...): (o: //eval.value(octalLit.'' rank (:.@))),
Expand Down Expand Up @@ -248,7 +261,7 @@ let evalExtend = \currentPackage \parsed
let evalStmt = \(?:currentPackage:'', ...) \parsed
cond parsed {
(:import, ...):
(import: {import.strLit.''(1) rank (:.@): () +> (cond import.modifier?:{} {('':mod, ...): (modifier: mod rank (:.@))} || ())}),
(import: {concatStrLit(import.strLit): () +> (cond import.modifier?:{} {('':mod, ...): (modifier: mod rank (:.@))} || ())}),
(:package, ...):
(package: {evalFullIdent(package.fullIdent): () +> evalComments(package)}),
(:option, ...): (
Expand Down
7 changes: 4 additions & 3 deletions pkg/importer/proto/proto_parser_test.arrai
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ let (:evalConstant, :parseFile, ...) = //{./proto_parser};
(
constant: (
string:
let constant = (strLit: ('': [153\'"', 154\'test', 231\'"']));
let constant = (strLit: ('': [153\'"', 231\'"'], @choice: [0], s: [('': [154\'test'])]));
let expected = (s: "test");
let actual = evalConstant(constant);
//test.assert.equal(expected, actual),
Expand All @@ -23,12 +23,12 @@ let (:evalConstant, :parseFile, ...) = //{./proto_parser};
let actual = evalConstant(constant);
//test.assert.equal(expected, actual),
object:
let constant = (object: (objectField: [('': 1390\':', objectKey: (constant: (fullIdent: (ident: [('': [1387\'g', 1388\'et'])]))), objectValue: (constant: (strLit: ('': [1392\'"', 1393\'/api/accounts', 1415\'"']))))]));
let constant = (object: (objectField: [('': 1390\':', objectKey: (constant: (fullIdent: (ident: [('': [1387\'g', 1388\'et'])]))), objectValue: (constant: (strLit: ('': [1392\'"', 1415\'"'], @choice: [0], s: [('': [1393\'/api/accounts'])]))))]));
let expected = (fields: {"get": (s: "/api/accounts")});
let actual = evalConstant(constant);
//test.assert.equal(expected, actual),
array:
let constant = (array: ('': [1497\'[', 1543\']'], arrayItem: [(constant: (strLit: ('': [1498\'"', 1499\'string', 1542\'"']))), (constant: (intLit: (decimalLit: ('': 235\'2'))))]));
let constant = (array: ('': [1497\'[', 1543\']'], arrayItem: [(constant: (strLit: ('': [1498\'"', 1542\'"'], @choice: [0], s: [('': [1499\'string'])]))), (constant: (intLit: (decimalLit: ('': 235\'2'))))]));
let expected = [(s: "string"), (d: 2)];
let actual = evalConstant(constant);
//test.assert.equal(expected, actual),
Expand Down Expand Up @@ -251,6 +251,7 @@ let (:evalConstant, :parseFile, ...) = //{./proto_parser};
options: {
'(my_option).a': (b: true),
'(object_option).a': (fields: {'array': [(d: 1), (s: 'string'), (fields: {'foo': (s: 'bar')})], 'object': (fields: {'foo': (s: 'bar')})}),
'adjacentString': (s: "firstsec'ondthi\"rdfourthfif't\"h"),
},
),
},
Expand Down
2 changes: 2 additions & 0 deletions pkg/importer/proto/tests/proto2.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ message Outer {
array: [1, "string", {foo: "bar"}],
object: {foo: "bar"}
};
option adjacentString = "first" "sec'ond"
"thi""rd" 'fourth' 'fif''t"h';

required int64 ival = 1;

Expand Down
2 changes: 1 addition & 1 deletion pkg/importer/proto/tests/proto2.sysl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ proto2:
!type Outer:
@description =:
| Level 1
@proto_options = ["(my_option).a = true", "(object_option).a = {\"array: [1, 'string', {'foo: bar'}]\", \"object: {'foo: bar'}\"}"]
@proto_options = ["(my_option).a = true", "(object_option).a = {\"array: [1, 'string', {'foo: bar'}]\", \"object: {'foo: bar'}\"}", "adjacentString = firstsec'ondthi\"rdfourthfif't\"h"]
@source_path = "proto/tests/proto2.proto"
enum_field <: EnumAllowingAlias?:
@json_tag = "enumField"
Expand Down

0 comments on commit f5435c3

Please sign in to comment.