ast_to_proto.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "explorer/fuzzing/ast_to_proto.h"
  5. #include <optional>
  6. #include "explorer/ast/declaration.h"
  7. #include "explorer/ast/expression.h"
  8. #include "llvm/Support/Casting.h"
  9. namespace Carbon::Testing {
  10. using ::llvm::cast;
  11. using ::llvm::dyn_cast;
  12. using ::llvm::isa;
  13. static auto ExpressionToProto(const Expression& expression)
  14. -> Fuzzing::Expression;
  15. static auto PatternToProto(const Pattern& pattern) -> Fuzzing::Pattern;
  16. static auto StatementToProto(const Statement& statement) -> Fuzzing::Statement;
  17. static auto DeclarationToProto(const Declaration& declaration)
  18. -> Fuzzing::Declaration;
  19. static auto LibraryNameToProto(const LibraryName& library_name)
  20. -> Fuzzing::LibraryName {
  21. Fuzzing::LibraryName library_name_proto;
  22. library_name_proto.set_package_name(library_name.package);
  23. if (!library_name.path.empty()) {
  24. library_name_proto.set_path(library_name.path);
  25. }
  26. return library_name_proto;
  27. }
  28. static auto OperatorToProtoEnum(const Operator op)
  29. -> Fuzzing::OperatorExpression::Operator {
  30. switch (op) {
  31. case Operator::AddressOf:
  32. return Fuzzing::OperatorExpression::AddressOf;
  33. case Operator::As:
  34. return Fuzzing::OperatorExpression::As;
  35. case Operator::Deref:
  36. return Fuzzing::OperatorExpression::Deref;
  37. case Operator::Neg:
  38. return Fuzzing::OperatorExpression::Neg;
  39. case Operator::Not:
  40. return Fuzzing::OperatorExpression::Not;
  41. case Operator::Ptr:
  42. return Fuzzing::OperatorExpression::Ptr;
  43. case Operator::Add:
  44. return Fuzzing::OperatorExpression::Add;
  45. case Operator::And:
  46. return Fuzzing::OperatorExpression::And;
  47. case Operator::Eq:
  48. return Fuzzing::OperatorExpression::Eq;
  49. case Operator::NotEq:
  50. return Fuzzing::OperatorExpression::NotEq;
  51. case Operator::Less:
  52. return Fuzzing::OperatorExpression::Less;
  53. case Operator::LessEq:
  54. return Fuzzing::OperatorExpression::LessEq;
  55. case Operator::Greater:
  56. return Fuzzing::OperatorExpression::Greater;
  57. case Operator::GreaterEq:
  58. return Fuzzing::OperatorExpression::GreaterEq;
  59. case Operator::Mul:
  60. return Fuzzing::OperatorExpression::Mul;
  61. case Operator::Div:
  62. return Fuzzing::OperatorExpression::Div;
  63. case Operator::Mod:
  64. return Fuzzing::OperatorExpression::Mod;
  65. case Operator::Or:
  66. return Fuzzing::OperatorExpression::Or;
  67. case Operator::Sub:
  68. return Fuzzing::OperatorExpression::Sub;
  69. case Operator::BitwiseAnd:
  70. return Fuzzing::OperatorExpression::BitwiseAnd;
  71. case Operator::BitwiseOr:
  72. return Fuzzing::OperatorExpression::BitwiseOr;
  73. case Operator::BitwiseXor:
  74. return Fuzzing::OperatorExpression::BitwiseXor;
  75. case Operator::BitShiftLeft:
  76. return Fuzzing::OperatorExpression::BitShiftLeft;
  77. case Operator::BitShiftRight:
  78. return Fuzzing::OperatorExpression::BitShiftRight;
  79. case Operator::Complement:
  80. return Fuzzing::OperatorExpression::Complement;
  81. }
  82. }
  83. static auto AssignOperatorToProtoEnum(const AssignOperator op)
  84. -> Fuzzing::AssignStatement::Operator {
  85. switch (op) {
  86. case AssignOperator::Plain:
  87. return Fuzzing::AssignStatement::Plain;
  88. case AssignOperator::Add:
  89. return Fuzzing::AssignStatement::Add;
  90. case AssignOperator::And:
  91. return Fuzzing::AssignStatement::And;
  92. case AssignOperator::Mul:
  93. return Fuzzing::AssignStatement::Mul;
  94. case AssignOperator::Div:
  95. return Fuzzing::AssignStatement::Div;
  96. case AssignOperator::Mod:
  97. return Fuzzing::AssignStatement::Mod;
  98. case AssignOperator::Or:
  99. return Fuzzing::AssignStatement::Or;
  100. case AssignOperator::ShiftLeft:
  101. return Fuzzing::AssignStatement::ShiftLeft;
  102. case AssignOperator::ShiftRight:
  103. return Fuzzing::AssignStatement::ShiftRight;
  104. case AssignOperator::Sub:
  105. return Fuzzing::AssignStatement::Sub;
  106. case AssignOperator::Xor:
  107. return Fuzzing::AssignStatement::Xor;
  108. }
  109. }
  110. static auto FieldInitializerToProto(const FieldInitializer& field)
  111. -> Fuzzing::FieldInitializer {
  112. Fuzzing::FieldInitializer field_proto;
  113. field_proto.set_name(field.name());
  114. *field_proto.mutable_expression() = ExpressionToProto(field.expression());
  115. return field_proto;
  116. }
  117. static auto TupleLiteralExpressionToProto(const TupleLiteral& tuple_literal)
  118. -> Fuzzing::TupleLiteralExpression {
  119. Fuzzing::TupleLiteralExpression tuple_literal_proto;
  120. for (Nonnull<const Expression*> field : tuple_literal.fields()) {
  121. *tuple_literal_proto.add_fields() = ExpressionToProto(*field);
  122. }
  123. return tuple_literal_proto;
  124. }
  125. static auto ExpressionToProto(const Expression& expression)
  126. -> Fuzzing::Expression {
  127. Fuzzing::Expression expression_proto;
  128. switch (expression.kind()) {
  129. case ExpressionKind::BaseAccessExpression:
  130. case ExpressionKind::ValueLiteral: {
  131. // This does not correspond to source syntax.
  132. break;
  133. }
  134. case ExpressionKind::BuiltinConvertExpression: {
  135. expression_proto = ExpressionToProto(
  136. *cast<BuiltinConvertExpression>(expression).source_expression());
  137. break;
  138. }
  139. case ExpressionKind::CallExpression: {
  140. const auto& call = cast<CallExpression>(expression);
  141. auto* call_proto = expression_proto.mutable_call();
  142. *call_proto->mutable_function() = ExpressionToProto(call.function());
  143. *call_proto->mutable_argument() = ExpressionToProto(call.argument());
  144. break;
  145. }
  146. case ExpressionKind::FunctionTypeLiteral: {
  147. const auto& fun_type = cast<FunctionTypeLiteral>(expression);
  148. auto* fun_type_proto = expression_proto.mutable_function_type();
  149. *fun_type_proto->mutable_parameter() =
  150. TupleLiteralExpressionToProto(fun_type.parameter());
  151. *fun_type_proto->mutable_return_type() =
  152. ExpressionToProto(fun_type.return_type());
  153. break;
  154. }
  155. case ExpressionKind::SimpleMemberAccessExpression: {
  156. const auto& simple_member_access =
  157. cast<SimpleMemberAccessExpression>(expression);
  158. if (isa<DotSelfExpression>(simple_member_access.object())) {
  159. // The parser rewrites `.Foo` into `.Self.Foo`. Undo this
  160. // transformation.
  161. auto* designator_proto = expression_proto.mutable_designator();
  162. designator_proto->set_name(simple_member_access.member_name());
  163. break;
  164. }
  165. auto* simple_member_access_proto =
  166. expression_proto.mutable_simple_member_access();
  167. simple_member_access_proto->set_field(simple_member_access.member_name());
  168. *simple_member_access_proto->mutable_object() =
  169. ExpressionToProto(simple_member_access.object());
  170. break;
  171. }
  172. case ExpressionKind::CompoundMemberAccessExpression: {
  173. const auto& simple_member_access =
  174. cast<CompoundMemberAccessExpression>(expression);
  175. auto* simple_member_access_proto =
  176. expression_proto.mutable_compound_member_access();
  177. *simple_member_access_proto->mutable_object() =
  178. ExpressionToProto(simple_member_access.object());
  179. *simple_member_access_proto->mutable_path() =
  180. ExpressionToProto(simple_member_access.path());
  181. break;
  182. }
  183. case ExpressionKind::IndexExpression: {
  184. const auto& index = cast<IndexExpression>(expression);
  185. auto* index_proto = expression_proto.mutable_index();
  186. *index_proto->mutable_object() = ExpressionToProto(index.object());
  187. *index_proto->mutable_offset() = ExpressionToProto(index.offset());
  188. break;
  189. }
  190. case ExpressionKind::OperatorExpression: {
  191. const auto& operator_expr = cast<OperatorExpression>(expression);
  192. auto* operator_proto = expression_proto.mutable_operator_();
  193. operator_proto->set_op(OperatorToProtoEnum(operator_expr.op()));
  194. for (Nonnull<const Expression*> arg : operator_expr.arguments()) {
  195. *operator_proto->add_arguments() = ExpressionToProto(*arg);
  196. }
  197. break;
  198. }
  199. case ExpressionKind::TupleLiteral:
  200. *expression_proto.mutable_tuple_literal() =
  201. TupleLiteralExpressionToProto(cast<TupleLiteral>(expression));
  202. break;
  203. case ExpressionKind::StructLiteral: {
  204. const auto& struct_literal = cast<StructLiteral>(expression);
  205. auto* struct_literal_proto = expression_proto.mutable_struct_literal();
  206. for (const FieldInitializer& field : struct_literal.fields()) {
  207. *struct_literal_proto->add_fields() = FieldInitializerToProto(field);
  208. }
  209. break;
  210. }
  211. case ExpressionKind::StructTypeLiteral: {
  212. const auto& struct_type_literal = cast<StructTypeLiteral>(expression);
  213. auto* struct_type_literal_proto =
  214. expression_proto.mutable_struct_type_literal();
  215. for (const FieldInitializer& field : struct_type_literal.fields()) {
  216. *struct_type_literal_proto->add_fields() =
  217. FieldInitializerToProto(field);
  218. }
  219. break;
  220. }
  221. case ExpressionKind::IdentifierExpression: {
  222. const auto& identifier = cast<IdentifierExpression>(expression);
  223. auto* identifier_proto = expression_proto.mutable_identifier();
  224. identifier_proto->set_name(identifier.name());
  225. break;
  226. }
  227. case ExpressionKind::WhereExpression: {
  228. const auto& where = cast<WhereExpression>(expression);
  229. auto* where_proto = expression_proto.mutable_where();
  230. *where_proto->mutable_base() =
  231. ExpressionToProto(where.self_binding().type());
  232. for (const WhereClause* where : where.clauses()) {
  233. Fuzzing::WhereClause clause_proto;
  234. switch (where->kind()) {
  235. case WhereClauseKind::ImplsWhereClause: {
  236. auto* impls_proto = clause_proto.mutable_impls();
  237. *impls_proto->mutable_type() =
  238. ExpressionToProto(cast<ImplsWhereClause>(where)->type());
  239. *impls_proto->mutable_constraint() =
  240. ExpressionToProto(cast<ImplsWhereClause>(where)->constraint());
  241. break;
  242. }
  243. case WhereClauseKind::EqualsWhereClause: {
  244. auto* equals_proto = clause_proto.mutable_equals();
  245. *equals_proto->mutable_lhs() =
  246. ExpressionToProto(cast<EqualsWhereClause>(where)->lhs());
  247. *equals_proto->mutable_rhs() =
  248. ExpressionToProto(cast<EqualsWhereClause>(where)->rhs());
  249. break;
  250. }
  251. case WhereClauseKind::RewriteWhereClause: {
  252. auto* rewrite = clause_proto.mutable_rewrite();
  253. rewrite->set_member_name(
  254. std::string(cast<RewriteWhereClause>(where)->member_name()));
  255. *rewrite->mutable_replacement() = ExpressionToProto(
  256. cast<RewriteWhereClause>(where)->replacement());
  257. break;
  258. }
  259. }
  260. *where_proto->add_clauses() = clause_proto;
  261. }
  262. break;
  263. }
  264. case ExpressionKind::DotSelfExpression: {
  265. auto* designator_proto = expression_proto.mutable_designator();
  266. designator_proto->set_name("Self");
  267. break;
  268. }
  269. case ExpressionKind::IntrinsicExpression: {
  270. const auto& intrinsic = cast<IntrinsicExpression>(expression);
  271. auto* call_proto = expression_proto.mutable_call();
  272. call_proto->mutable_function()->mutable_identifier()->set_name(
  273. std::string(intrinsic.name()));
  274. *call_proto->mutable_argument() = ExpressionToProto(intrinsic.args());
  275. break;
  276. }
  277. case ExpressionKind::IfExpression: {
  278. const auto& if_expression = cast<IfExpression>(expression);
  279. auto* if_proto = expression_proto.mutable_if_expression();
  280. *if_proto->mutable_condition() =
  281. ExpressionToProto(if_expression.condition());
  282. *if_proto->mutable_then_expression() =
  283. ExpressionToProto(if_expression.then_expression());
  284. *if_proto->mutable_else_expression() =
  285. ExpressionToProto(if_expression.else_expression());
  286. break;
  287. }
  288. case ExpressionKind::BoolTypeLiteral:
  289. expression_proto.mutable_bool_type_literal();
  290. break;
  291. case ExpressionKind::BoolLiteral:
  292. expression_proto.mutable_bool_literal()->set_value(
  293. cast<BoolLiteral>(expression).value());
  294. break;
  295. case ExpressionKind::IntTypeLiteral:
  296. expression_proto.mutable_int_type_literal();
  297. break;
  298. case ExpressionKind::IntLiteral:
  299. expression_proto.mutable_int_literal()->set_value(
  300. cast<IntLiteral>(expression).value());
  301. break;
  302. case ExpressionKind::StringLiteral:
  303. expression_proto.mutable_string_literal()->set_value(
  304. cast<StringLiteral>(expression).value());
  305. break;
  306. case ExpressionKind::StringTypeLiteral:
  307. expression_proto.mutable_string_type_literal();
  308. break;
  309. case ExpressionKind::TypeTypeLiteral:
  310. expression_proto.mutable_type_type_literal();
  311. break;
  312. case ExpressionKind::UnimplementedExpression:
  313. expression_proto.mutable_unimplemented_expression();
  314. break;
  315. case ExpressionKind::ArrayTypeLiteral: {
  316. const auto& array_literal = cast<ArrayTypeLiteral>(expression);
  317. Fuzzing::ArrayTypeLiteral* array_literal_proto =
  318. expression_proto.mutable_array_type_literal();
  319. *array_literal_proto->mutable_element_type() =
  320. ExpressionToProto(array_literal.element_type_expression());
  321. if (array_literal.has_size_expression()) {
  322. *array_literal_proto->mutable_size() =
  323. ExpressionToProto(array_literal.size_expression());
  324. }
  325. break;
  326. }
  327. }
  328. return expression_proto;
  329. }
  330. static auto BindingPatternToProto(const BindingPattern& pattern)
  331. -> Fuzzing::BindingPattern {
  332. Fuzzing::BindingPattern pattern_proto;
  333. pattern_proto.set_name(pattern.name());
  334. *pattern_proto.mutable_type() = PatternToProto(pattern.type());
  335. return pattern_proto;
  336. }
  337. static auto GenericBindingToProto(const GenericBinding& binding)
  338. -> Fuzzing::GenericBinding {
  339. Fuzzing::GenericBinding binding_proto;
  340. binding_proto.set_name(binding.name());
  341. *binding_proto.mutable_type() = ExpressionToProto(binding.type());
  342. switch (binding.binding_kind()) {
  343. case GenericBinding::BindingKind::Checked:
  344. binding_proto.set_kind(Fuzzing::GenericBinding::Checked);
  345. break;
  346. case GenericBinding::BindingKind::Template:
  347. binding_proto.set_kind(Fuzzing::GenericBinding::Template);
  348. break;
  349. }
  350. return binding_proto;
  351. }
  352. static auto TuplePatternToProto(const TuplePattern& tuple_pattern)
  353. -> Fuzzing::TuplePattern {
  354. Fuzzing::TuplePattern tuple_pattern_proto;
  355. for (Nonnull<const Pattern*> field : tuple_pattern.fields()) {
  356. *tuple_pattern_proto.add_fields() = PatternToProto(*field);
  357. }
  358. return tuple_pattern_proto;
  359. }
  360. static auto PatternToProto(const Pattern& pattern) -> Fuzzing::Pattern {
  361. Fuzzing::Pattern pattern_proto;
  362. switch (pattern.kind()) {
  363. case PatternKind::GenericBinding: {
  364. const auto& binding = cast<GenericBinding>(pattern);
  365. *pattern_proto.mutable_generic_binding() = GenericBindingToProto(binding);
  366. break;
  367. }
  368. case PatternKind::BindingPattern: {
  369. const auto& binding = cast<BindingPattern>(pattern);
  370. *pattern_proto.mutable_binding_pattern() = BindingPatternToProto(binding);
  371. break;
  372. }
  373. case PatternKind::TuplePattern:
  374. *pattern_proto.mutable_tuple_pattern() =
  375. TuplePatternToProto(cast<TuplePattern>(pattern));
  376. break;
  377. case PatternKind::AlternativePattern: {
  378. const auto& alternative = cast<AlternativePattern>(pattern);
  379. auto* alternative_proto = pattern_proto.mutable_alternative_pattern();
  380. alternative_proto->set_alternative_name(alternative.alternative_name());
  381. *alternative_proto->mutable_choice_type() =
  382. ExpressionToProto(alternative.choice_type());
  383. *alternative_proto->mutable_arguments() =
  384. TuplePatternToProto(alternative.arguments());
  385. break;
  386. }
  387. case PatternKind::ExpressionPattern:
  388. *pattern_proto.mutable_expression_pattern()->mutable_expression() =
  389. ExpressionToProto(cast<ExpressionPattern>(pattern).expression());
  390. break;
  391. case PatternKind::AutoPattern:
  392. pattern_proto.mutable_auto_pattern();
  393. break;
  394. case PatternKind::VarPattern:
  395. *pattern_proto.mutable_var_pattern()->mutable_pattern() =
  396. PatternToProto(cast<VarPattern>(pattern).pattern());
  397. break;
  398. case PatternKind::AddrPattern:
  399. *pattern_proto.mutable_addr_pattern()->mutable_binding_pattern() =
  400. BindingPatternToProto(cast<AddrPattern>(pattern).binding());
  401. break;
  402. }
  403. return pattern_proto;
  404. }
  405. static auto BlockStatementToProto(const Block& block)
  406. -> Fuzzing::BlockStatement {
  407. Fuzzing::BlockStatement block_proto;
  408. for (Nonnull<const Statement*> statement : block.statements()) {
  409. *block_proto.add_statements() = StatementToProto(*statement);
  410. }
  411. return block_proto;
  412. }
  413. static auto StatementToProto(const Statement& statement) -> Fuzzing::Statement {
  414. Fuzzing::Statement statement_proto;
  415. switch (statement.kind()) {
  416. case StatementKind::ExpressionStatement:
  417. *statement_proto.mutable_expression_statement()->mutable_expression() =
  418. ExpressionToProto(cast<ExpressionStatement>(statement).expression());
  419. break;
  420. case StatementKind::Assign: {
  421. const auto& assign = cast<Assign>(statement);
  422. auto* assign_proto = statement_proto.mutable_assign();
  423. *assign_proto->mutable_lhs() = ExpressionToProto(assign.lhs());
  424. *assign_proto->mutable_rhs() = ExpressionToProto(assign.rhs());
  425. assign_proto->set_op(AssignOperatorToProtoEnum(assign.op()));
  426. break;
  427. }
  428. case StatementKind::IncrementDecrement: {
  429. const auto& inc_dec = cast<IncrementDecrement>(statement);
  430. auto* inc_dec_proto = statement_proto.mutable_inc_dec();
  431. *inc_dec_proto->mutable_operand() = ExpressionToProto(inc_dec.argument());
  432. inc_dec_proto->set_is_increment(inc_dec.is_increment());
  433. break;
  434. }
  435. case StatementKind::VariableDefinition: {
  436. const auto& def = cast<VariableDefinition>(statement);
  437. auto* def_proto = statement_proto.mutable_variable_definition();
  438. *def_proto->mutable_pattern() = PatternToProto(def.pattern());
  439. if (def.has_init()) {
  440. *def_proto->mutable_init() = ExpressionToProto(def.init());
  441. }
  442. def_proto->set_is_returned(def.is_returned());
  443. break;
  444. }
  445. case StatementKind::If: {
  446. const auto& if_stmt = cast<If>(statement);
  447. auto* if_proto = statement_proto.mutable_if_statement();
  448. *if_proto->mutable_condition() = ExpressionToProto(if_stmt.condition());
  449. *if_proto->mutable_then_block() =
  450. BlockStatementToProto(if_stmt.then_block());
  451. if (if_stmt.else_block().has_value()) {
  452. *if_proto->mutable_else_block() =
  453. BlockStatementToProto(**if_stmt.else_block());
  454. }
  455. break;
  456. }
  457. case StatementKind::ReturnVar: {
  458. statement_proto.mutable_return_var_statement();
  459. break;
  460. }
  461. case StatementKind::ReturnExpression: {
  462. const auto& ret = cast<ReturnExpression>(statement);
  463. auto* ret_proto = statement_proto.mutable_return_expression_statement();
  464. if (!ret.is_omitted_expression()) {
  465. *ret_proto->mutable_expression() = ExpressionToProto(ret.expression());
  466. } else {
  467. ret_proto->set_is_omitted_expression(true);
  468. }
  469. break;
  470. }
  471. case StatementKind::Block:
  472. *statement_proto.mutable_block() =
  473. BlockStatementToProto(cast<Block>(statement));
  474. break;
  475. case StatementKind::While: {
  476. const auto& while_stmt = cast<While>(statement);
  477. auto* while_proto = statement_proto.mutable_while_statement();
  478. *while_proto->mutable_condition() =
  479. ExpressionToProto(while_stmt.condition());
  480. *while_proto->mutable_body() = BlockStatementToProto(while_stmt.body());
  481. break;
  482. }
  483. case StatementKind::Match: {
  484. const auto& match = cast<Match>(statement);
  485. auto* match_proto = statement_proto.mutable_match();
  486. *match_proto->mutable_expression() =
  487. ExpressionToProto(match.expression());
  488. for (const Match::Clause& clause : match.clauses()) {
  489. auto* clause_proto = match_proto->add_clauses();
  490. // TODO: Working out whether we have a default clause after the fact
  491. // like this is fragile.
  492. bool is_default_clause = false;
  493. if (const auto* binding = dyn_cast<BindingPattern>(&clause.pattern())) {
  494. if (binding->name() == AnonymousName &&
  495. isa<AutoPattern>(binding->type()) &&
  496. binding->source_loc() == binding->type().source_loc()) {
  497. is_default_clause = true;
  498. }
  499. }
  500. if (is_default_clause) {
  501. clause_proto->set_is_default(true);
  502. } else {
  503. *clause_proto->mutable_pattern() = PatternToProto(clause.pattern());
  504. }
  505. *clause_proto->mutable_statement() =
  506. StatementToProto(clause.statement());
  507. }
  508. break;
  509. }
  510. case StatementKind::Break:
  511. // Initializes with the default value; there's nothing to set.
  512. statement_proto.mutable_break_statement();
  513. break;
  514. case StatementKind::Continue:
  515. // Initializes with the default value; there's nothing to set.
  516. statement_proto.mutable_continue_statement();
  517. break;
  518. case StatementKind::For: {
  519. const auto& for_stmt = cast<For>(statement);
  520. auto* for_proto = statement_proto.mutable_for_statement();
  521. *for_proto->mutable_var_decl() =
  522. BindingPatternToProto(for_stmt.variable_declaration());
  523. *for_proto->mutable_target() = ExpressionToProto(for_stmt.loop_target());
  524. *for_proto->mutable_body() = BlockStatementToProto(for_stmt.body());
  525. break;
  526. }
  527. }
  528. return statement_proto;
  529. }
  530. static auto ReturnTermToProto(const ReturnTerm& return_term)
  531. -> Fuzzing::ReturnTerm {
  532. Fuzzing::ReturnTerm return_term_proto;
  533. if (return_term.is_omitted()) {
  534. return_term_proto.set_kind(Fuzzing::ReturnTerm::Omitted);
  535. } else if (return_term.is_auto()) {
  536. return_term_proto.set_kind(Fuzzing::ReturnTerm::Auto);
  537. } else {
  538. return_term_proto.set_kind(Fuzzing::ReturnTerm::Expression);
  539. *return_term_proto.mutable_type() =
  540. ExpressionToProto(**return_term.type_expression());
  541. }
  542. return return_term_proto;
  543. }
  544. static auto DeclaredNameToProto(const DeclaredName& name)
  545. -> Fuzzing::DeclaredName {
  546. Fuzzing::DeclaredName name_proto;
  547. name_proto.set_name(std::string(name.inner_name()));
  548. for (const auto& [loc, qual] : name.qualifiers()) {
  549. name_proto.add_qualifiers(qual);
  550. }
  551. return name_proto;
  552. }
  553. static auto DeclarationToProto(const Declaration& declaration)
  554. -> Fuzzing::Declaration {
  555. Fuzzing::Declaration declaration_proto;
  556. switch (declaration.kind()) {
  557. case DeclarationKind::NamespaceDeclaration: {
  558. const auto& namespace_decl = cast<NamespaceDeclaration>(declaration);
  559. auto* namespace_proto = declaration_proto.mutable_namespace_();
  560. *namespace_proto->mutable_name() =
  561. DeclaredNameToProto(namespace_decl.name());
  562. break;
  563. }
  564. case DeclarationKind::DestructorDeclaration: {
  565. const auto& function = cast<DestructorDeclaration>(declaration);
  566. auto* function_proto = declaration_proto.mutable_destructor();
  567. if (function.is_method()) {
  568. switch (function.self_pattern().kind()) {
  569. case PatternKind::AddrPattern:
  570. *function_proto->mutable_self_pattern() =
  571. PatternToProto(cast<AddrPattern>(function.self_pattern()));
  572. break;
  573. case PatternKind::BindingPattern:
  574. *function_proto->mutable_self_pattern() =
  575. PatternToProto(cast<BindingPattern>(function.self_pattern()));
  576. break;
  577. default:
  578. // Parser shouldn't allow self_pattern to be anything other than
  579. // AddrPattern or BindingPattern
  580. CARBON_FATAL()
  581. << "self_pattern in method declaration can be either "
  582. "AddrPattern or BindingPattern. Actual pattern: "
  583. << function.self_pattern();
  584. break;
  585. }
  586. }
  587. if (function.body().has_value()) {
  588. *function_proto->mutable_body() =
  589. BlockStatementToProto(**function.body());
  590. }
  591. break;
  592. }
  593. case DeclarationKind::FunctionDeclaration: {
  594. const auto& function = cast<FunctionDeclaration>(declaration);
  595. auto* function_proto = declaration_proto.mutable_function();
  596. *function_proto->mutable_name() = DeclaredNameToProto(function.name());
  597. for (Nonnull<const GenericBinding*> binding :
  598. function.deduced_parameters()) {
  599. *function_proto->add_deduced_parameters() =
  600. GenericBindingToProto(*binding);
  601. }
  602. if (function.is_method()) {
  603. switch (function.self_pattern().kind()) {
  604. case PatternKind::AddrPattern:
  605. *function_proto->mutable_self_pattern() =
  606. PatternToProto(cast<AddrPattern>(function.self_pattern()));
  607. break;
  608. case PatternKind::BindingPattern:
  609. *function_proto->mutable_self_pattern() =
  610. PatternToProto(cast<BindingPattern>(function.self_pattern()));
  611. break;
  612. default:
  613. // Parser shouldn't allow self_pattern to be anything other than
  614. // AddrPattern or BindingPattern
  615. CARBON_FATAL()
  616. << "self_pattern in method declaration can be either "
  617. "AddrPattern or BindingPattern. Actual pattern: "
  618. << function.self_pattern();
  619. break;
  620. }
  621. }
  622. *function_proto->mutable_param_pattern() =
  623. TuplePatternToProto(function.param_pattern());
  624. *function_proto->mutable_return_term() =
  625. ReturnTermToProto(function.return_term());
  626. if (function.body().has_value()) {
  627. *function_proto->mutable_body() =
  628. BlockStatementToProto(**function.body());
  629. }
  630. break;
  631. }
  632. case DeclarationKind::ClassDeclaration: {
  633. const auto& class_decl = cast<ClassDeclaration>(declaration);
  634. auto* class_proto = declaration_proto.mutable_class_declaration();
  635. *class_proto->mutable_name() = DeclaredNameToProto(class_decl.name());
  636. if (class_decl.type_params().has_value()) {
  637. *class_proto->mutable_type_params() =
  638. TuplePatternToProto(**class_decl.type_params());
  639. }
  640. for (Nonnull<const Declaration*> member : class_decl.members()) {
  641. *class_proto->add_members() = DeclarationToProto(*member);
  642. }
  643. break;
  644. }
  645. case DeclarationKind::MixinDeclaration: {
  646. const auto& mixin = cast<MixinDeclaration>(declaration);
  647. auto* mixin_proto = declaration_proto.mutable_mixin();
  648. *mixin_proto->mutable_name() = DeclaredNameToProto(mixin.name());
  649. for (const auto& member : mixin.members()) {
  650. *mixin_proto->add_members() = DeclarationToProto(*member);
  651. }
  652. // Type params not implemented yet
  653. // if (mixin.params().has_value()) {
  654. // *mixin_proto->mutable_params() =
  655. // TuplePatternToProto(**mixin.params());
  656. //}
  657. *mixin_proto->mutable_self() = GenericBindingToProto(*mixin.self());
  658. break;
  659. }
  660. case DeclarationKind::MixDeclaration: {
  661. const auto& mix = cast<MixDeclaration>(declaration);
  662. auto* mix_proto = declaration_proto.mutable_mix();
  663. *mix_proto->mutable_mixin() = ExpressionToProto(mix.mixin());
  664. break;
  665. }
  666. case DeclarationKind::ChoiceDeclaration: {
  667. const auto& choice = cast<ChoiceDeclaration>(declaration);
  668. auto* choice_proto = declaration_proto.mutable_choice();
  669. *choice_proto->mutable_name() = DeclaredNameToProto(choice.name());
  670. for (Nonnull<const AlternativeSignature*> alternative :
  671. choice.alternatives()) {
  672. auto* alternative_proto = choice_proto->add_alternatives();
  673. alternative_proto->set_name(alternative->name());
  674. if (auto params = alternative->parameters()) {
  675. *alternative_proto->mutable_signature() =
  676. TupleLiteralExpressionToProto(**params);
  677. }
  678. }
  679. break;
  680. }
  681. case DeclarationKind::VariableDeclaration: {
  682. const auto& var = cast<VariableDeclaration>(declaration);
  683. auto* var_proto = declaration_proto.mutable_variable();
  684. *var_proto->mutable_binding() = BindingPatternToProto(var.binding());
  685. if (var.has_initializer()) {
  686. *var_proto->mutable_initializer() =
  687. ExpressionToProto(var.initializer());
  688. }
  689. break;
  690. }
  691. case DeclarationKind::InterfaceExtendDeclaration: {
  692. const auto& extend = cast<InterfaceExtendDeclaration>(declaration);
  693. auto* extend_proto = declaration_proto.mutable_interface_extend();
  694. *extend_proto->mutable_base() = ExpressionToProto(*extend.base());
  695. break;
  696. }
  697. case DeclarationKind::InterfaceRequireDeclaration: {
  698. const auto& require = cast<InterfaceRequireDeclaration>(declaration);
  699. auto* require_proto = declaration_proto.mutable_interface_require();
  700. *require_proto->mutable_impl_type() =
  701. ExpressionToProto(*require.impl_type());
  702. *require_proto->mutable_constraint() =
  703. ExpressionToProto(*require.constraint());
  704. break;
  705. }
  706. case DeclarationKind::AssociatedConstantDeclaration: {
  707. const auto& assoc = cast<AssociatedConstantDeclaration>(declaration);
  708. auto* let_proto = declaration_proto.mutable_let();
  709. *let_proto->mutable_pattern() = PatternToProto(assoc.binding());
  710. break;
  711. }
  712. case DeclarationKind::InterfaceDeclaration: {
  713. const auto& interface = cast<InterfaceDeclaration>(declaration);
  714. auto* interface_proto = declaration_proto.mutable_interface();
  715. *interface_proto->mutable_name() = DeclaredNameToProto(interface.name());
  716. for (const auto& member : interface.members()) {
  717. *interface_proto->add_members() = DeclarationToProto(*member);
  718. }
  719. break;
  720. }
  721. case DeclarationKind::ConstraintDeclaration: {
  722. const auto& constraint = cast<ConstraintDeclaration>(declaration);
  723. auto* constraint_proto = declaration_proto.mutable_constraint();
  724. *constraint_proto->mutable_name() =
  725. DeclaredNameToProto(constraint.name());
  726. for (const auto& member : constraint.members()) {
  727. *constraint_proto->add_members() = DeclarationToProto(*member);
  728. }
  729. break;
  730. }
  731. case DeclarationKind::ImplDeclaration: {
  732. const auto& impl = cast<ImplDeclaration>(declaration);
  733. auto* impl_proto = declaration_proto.mutable_impl();
  734. switch (impl.kind()) {
  735. case ImplKind::InternalImpl:
  736. impl_proto->set_kind(Fuzzing::ImplDeclaration::InternalImpl);
  737. break;
  738. case ImplKind::ExternalImpl:
  739. impl_proto->set_kind(Fuzzing::ImplDeclaration::ExternalImpl);
  740. break;
  741. }
  742. for (Nonnull<const GenericBinding*> binding : impl.deduced_parameters()) {
  743. *impl_proto->add_deduced_parameters() = GenericBindingToProto(*binding);
  744. }
  745. *impl_proto->mutable_impl_type() = ExpressionToProto(*impl.impl_type());
  746. *impl_proto->mutable_interface() = ExpressionToProto(impl.interface());
  747. for (const auto& member : impl.members()) {
  748. *impl_proto->add_members() = DeclarationToProto(*member);
  749. }
  750. break;
  751. }
  752. case DeclarationKind::MatchFirstDeclaration: {
  753. const auto& match_first = cast<MatchFirstDeclaration>(declaration);
  754. auto* match_first_proto = declaration_proto.mutable_match_first();
  755. for (const auto* impl : match_first.impl_declarations()) {
  756. *match_first_proto->add_impl_declarations() = DeclarationToProto(*impl);
  757. }
  758. break;
  759. }
  760. case DeclarationKind::SelfDeclaration: {
  761. CARBON_FATAL() << "Unreachable SelfDeclaration in DeclarationToProto().";
  762. }
  763. case DeclarationKind::AliasDeclaration: {
  764. const auto& alias = cast<AliasDeclaration>(declaration);
  765. auto* alias_proto = declaration_proto.mutable_alias();
  766. *alias_proto->mutable_name() = DeclaredNameToProto(alias.name());
  767. *alias_proto->mutable_target() = ExpressionToProto(alias.target());
  768. break;
  769. }
  770. case DeclarationKind::ExtendBaseDeclaration: {
  771. const auto& extend_base = cast<ExtendBaseDeclaration>(declaration);
  772. auto* extend_base_proto = declaration_proto.mutable_extend_base();
  773. *extend_base_proto->mutable_base_class() =
  774. ExpressionToProto(*extend_base.base_class());
  775. break;
  776. }
  777. }
  778. return declaration_proto;
  779. }
  780. auto AstToProto(const AST& ast) -> Fuzzing::Carbon {
  781. Fuzzing::Carbon carbon;
  782. auto* unit = carbon.mutable_compilation_unit();
  783. *unit->mutable_package_statement() = LibraryNameToProto(ast.package);
  784. unit->set_is_api(ast.is_api);
  785. for (const Declaration* declaration : ast.declarations) {
  786. *unit->add_declarations() = DeclarationToProto(*declaration);
  787. }
  788. return carbon;
  789. }
  790. } // namespace Carbon::Testing