diff --git a/third-party/thrift/src/thrift/compiler/codemod/structure_annotations.cc b/third-party/thrift/src/thrift/compiler/codemod/structure_annotations.cc index 1f4c774e692eeb..fbcc26d7243b8f 100644 --- a/third-party/thrift/src/thrift/compiler/codemod/structure_annotations.cc +++ b/third-party/thrift/src/thrift/compiler/codemod/structure_annotations.cc @@ -33,6 +33,22 @@ bool is_container(const t_type& type) { return true_type && true_type->is_container(); } +std::string quote(std::string_view str) { + if (str.find('"') == std::string::npos) { + return fmt::format("\"{}\"", str); + } else if (str.find('\'') == std::string::npos) { + return fmt::format("'{}'", str); + } else { + std::string out(str); + size_t start_pos = 0; + while ((start_pos = out.find('"', start_pos)) != std::string::npos) { + out.replace(start_pos, 1, "\\\""); + start_pos += 2; + } + return fmt::format("\"{}\"", out); + } +} + class structure_annotations { public: structure_annotations(source_manager& sm, t_program& program) @@ -516,7 +532,7 @@ class structure_annotations { std::vector annotations_for_catch_all_strs; for (const auto& [name, value] : annotations_for_catch_all) { annotations_for_catch_all_strs.push_back( - fmt::format(R"("{}": "{}")", name, value)); + fmt::format(R"("{}": {})", name, quote(value))); } to_add.insert(fmt::format( "@thrift.DeprecatedUnvalidatedAnnotations{{items = {{{}}}}}", diff --git a/third-party/thrift/src/thrift/compiler/codemod/structure_annotations_test.py b/third-party/thrift/src/thrift/compiler/codemod/structure_annotations_test.py index 549f032692bf2d..5340204a6c63b3 100644 --- a/third-party/thrift/src/thrift/compiler/codemod/structure_annotations_test.py +++ b/third-party/thrift/src/thrift/compiler/codemod/structure_annotations_test.py @@ -489,7 +489,7 @@ def test_remaining(self): include "thrift.thrift" struct S { - 1: i32 field1 (foo); + 1: i32 field1 (foo, quote = '"', both_quotes = "'\\"'"); }(foo, bar = "baz") typedef i32 (foo, hs.type = "hs") T (bar = "baz", hs.category = "value") @@ -530,7 +530,7 @@ def test_remaining(self): @thrift.DeprecatedUnvalidatedAnnotations{items = {"bar": "baz", "foo": "1"}} struct S { - @thrift.DeprecatedUnvalidatedAnnotations{items = {"foo": "1"}} + @thrift.DeprecatedUnvalidatedAnnotations{items = {"both_quotes": "'\\"'", "foo": "1", "quote": '"'}} 1: i32 field1 ; }