ast_to_proto.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  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 {
  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::Mod:
  62. return Fuzzing::OperatorExpression::Mod;
  63. case Operator::Or:
  64. return Fuzzing::OperatorExpression::Or;
  65. case Operator::Sub:
  66. return Fuzzing::OperatorExpression::Sub;
  67. case Operator::BitwiseAnd:
  68. return Fuzzing::OperatorExpression::BitwiseAnd;
  69. case Operator::BitwiseOr:
  70. return Fuzzing::OperatorExpression::BitwiseOr;
  71. case Operator::BitwiseXor:
  72. return Fuzzing::OperatorExpression::BitwiseXor;
  73. case Operator::BitShiftLeft:
  74. return Fuzzing::OperatorExpression::BitShiftLeft;
  75. case Operator::BitShiftRight:
  76. return Fuzzing::OperatorExpression::BitShiftRight;
  77. case Operator::Complement:
  78. return Fuzzing::OperatorExpression::Complement;
  79. }
  80. }
  81. static auto FieldInitializerToProto(const FieldInitializer& field)
  82. -> Fuzzing::FieldInitializer {
  83. Fuzzing::FieldInitializer field_proto;
  84. field_proto.set_name(field.name());
  85. *field_proto.mutable_expression() = ExpressionToProto(field.expression());
  86. return field_proto;
  87. }
  88. static auto TupleLiteralExpressionToProto(const TupleLiteral& tuple_literal)
  89. -> Fuzzing::TupleLiteralExpression {
  90. Fuzzing::TupleLiteralExpression tuple_literal_proto;
  91. for (Nonnull<const Expression*> field : tuple_literal.fields()) {
  92. *tuple_literal_proto.add_fields() = ExpressionToProto(*field);
  93. }
  94. return tuple_literal_proto;
  95. }
  96. static auto ExpressionToProto(const Expression& expression)
  97. -> Fuzzing::Expression {
  98. Fuzzing::Expression expression_proto;
  99. switch (expression.kind()) {
  100. case ExpressionKind::InstantiateImpl:
  101. case ExpressionKind::ValueLiteral: {
  102. // These do not correspond to source syntax.
  103. break;
  104. }
  105. case ExpressionKind::CallExpression: {
  106. const auto& call = cast<CallExpression>(expression);
  107. auto* call_proto = expression_proto.mutable_call();
  108. *call_proto->mutable_function() = ExpressionToProto(call.function());
  109. *call_proto->mutable_argument() = ExpressionToProto(call.argument());
  110. break;
  111. }
  112. case ExpressionKind::FunctionTypeLiteral: {
  113. const auto& fun_type = cast<FunctionTypeLiteral>(expression);
  114. auto* fun_type_proto = expression_proto.mutable_function_type();
  115. *fun_type_proto->mutable_parameter() =
  116. TupleLiteralExpressionToProto(fun_type.parameter());
  117. *fun_type_proto->mutable_return_type() =
  118. ExpressionToProto(fun_type.return_type());
  119. break;
  120. }
  121. case ExpressionKind::SimpleMemberAccessExpression: {
  122. const auto& simple_member_access =
  123. cast<SimpleMemberAccessExpression>(expression);
  124. if (isa<DotSelfExpression>(simple_member_access.object())) {
  125. // The parser rewrites `.Foo` into `.Self.Foo`. Undo this
  126. // transformation.
  127. auto* designator_proto = expression_proto.mutable_designator();
  128. designator_proto->set_name(simple_member_access.member_name());
  129. break;
  130. }
  131. auto* simple_member_access_proto =
  132. expression_proto.mutable_simple_member_access();
  133. simple_member_access_proto->set_field(simple_member_access.member_name());
  134. *simple_member_access_proto->mutable_object() =
  135. ExpressionToProto(simple_member_access.object());
  136. break;
  137. }
  138. case ExpressionKind::CompoundMemberAccessExpression: {
  139. const auto& simple_member_access =
  140. cast<CompoundMemberAccessExpression>(expression);
  141. auto* simple_member_access_proto =
  142. expression_proto.mutable_compound_member_access();
  143. *simple_member_access_proto->mutable_object() =
  144. ExpressionToProto(simple_member_access.object());
  145. *simple_member_access_proto->mutable_path() =
  146. ExpressionToProto(simple_member_access.path());
  147. break;
  148. }
  149. case ExpressionKind::IndexExpression: {
  150. const auto& index = cast<IndexExpression>(expression);
  151. auto* index_proto = expression_proto.mutable_index();
  152. *index_proto->mutable_object() = ExpressionToProto(index.object());
  153. *index_proto->mutable_offset() = ExpressionToProto(index.offset());
  154. break;
  155. }
  156. case ExpressionKind::OperatorExpression: {
  157. const auto& operator_expr = cast<OperatorExpression>(expression);
  158. auto* operator_proto = expression_proto.mutable_operator_();
  159. operator_proto->set_op(OperatorToProtoEnum(operator_expr.op()));
  160. for (Nonnull<const Expression*> arg : operator_expr.arguments()) {
  161. *operator_proto->add_arguments() = ExpressionToProto(*arg);
  162. }
  163. break;
  164. }
  165. case ExpressionKind::TupleLiteral:
  166. *expression_proto.mutable_tuple_literal() =
  167. TupleLiteralExpressionToProto(cast<TupleLiteral>(expression));
  168. break;
  169. case ExpressionKind::StructLiteral: {
  170. const auto& struct_literal = cast<StructLiteral>(expression);
  171. auto* struct_literal_proto = expression_proto.mutable_struct_literal();
  172. for (const FieldInitializer& field : struct_literal.fields()) {
  173. *struct_literal_proto->add_fields() = FieldInitializerToProto(field);
  174. }
  175. break;
  176. }
  177. case ExpressionKind::StructTypeLiteral: {
  178. const auto& struct_type_literal = cast<StructTypeLiteral>(expression);
  179. auto* struct_type_literal_proto =
  180. expression_proto.mutable_struct_type_literal();
  181. for (const FieldInitializer& field : struct_type_literal.fields()) {
  182. *struct_type_literal_proto->add_fields() =
  183. FieldInitializerToProto(field);
  184. }
  185. break;
  186. }
  187. case ExpressionKind::IdentifierExpression: {
  188. const auto& identifier = cast<IdentifierExpression>(expression);
  189. auto* identifier_proto = expression_proto.mutable_identifier();
  190. identifier_proto->set_name(identifier.name());
  191. break;
  192. }
  193. case ExpressionKind::WhereExpression: {
  194. const auto& where = cast<WhereExpression>(expression);
  195. auto* where_proto = expression_proto.mutable_where();
  196. *where_proto->mutable_base() =
  197. ExpressionToProto(where.self_binding().type());
  198. for (const WhereClause* where : where.clauses()) {
  199. Fuzzing::WhereClause clause_proto;
  200. switch (where->kind()) {
  201. case WhereClauseKind::IsWhereClause: {
  202. auto* is_proto = clause_proto.mutable_is();
  203. *is_proto->mutable_type() =
  204. ExpressionToProto(cast<IsWhereClause>(where)->type());
  205. *is_proto->mutable_constraint() =
  206. ExpressionToProto(cast<IsWhereClause>(where)->constraint());
  207. break;
  208. }
  209. case WhereClauseKind::EqualsWhereClause: {
  210. auto* equals_proto = clause_proto.mutable_equals();
  211. *equals_proto->mutable_lhs() =
  212. ExpressionToProto(cast<EqualsWhereClause>(where)->lhs());
  213. *equals_proto->mutable_rhs() =
  214. ExpressionToProto(cast<EqualsWhereClause>(where)->rhs());
  215. break;
  216. }
  217. }
  218. *where_proto->add_clauses() = clause_proto;
  219. }
  220. break;
  221. }
  222. case ExpressionKind::DotSelfExpression: {
  223. auto* designator_proto = expression_proto.mutable_designator();
  224. designator_proto->set_name("Self");
  225. break;
  226. }
  227. case ExpressionKind::IntrinsicExpression: {
  228. const auto& intrinsic = cast<IntrinsicExpression>(expression);
  229. auto* call_proto = expression_proto.mutable_call();
  230. call_proto->mutable_function()->mutable_identifier()->set_name(
  231. std::string(intrinsic.name()));
  232. *call_proto->mutable_argument() = ExpressionToProto(intrinsic.args());
  233. break;
  234. }
  235. case ExpressionKind::IfExpression: {
  236. const auto& if_expression = cast<IfExpression>(expression);
  237. auto* if_proto = expression_proto.mutable_if_expression();
  238. *if_proto->mutable_condition() =
  239. ExpressionToProto(if_expression.condition());
  240. *if_proto->mutable_then_expression() =
  241. ExpressionToProto(if_expression.then_expression());
  242. *if_proto->mutable_else_expression() =
  243. ExpressionToProto(if_expression.else_expression());
  244. break;
  245. }
  246. case ExpressionKind::BoolTypeLiteral:
  247. expression_proto.mutable_bool_type_literal();
  248. break;
  249. case ExpressionKind::BoolLiteral:
  250. expression_proto.mutable_bool_literal()->set_value(
  251. cast<BoolLiteral>(expression).value());
  252. break;
  253. case ExpressionKind::IntTypeLiteral:
  254. expression_proto.mutable_int_type_literal();
  255. break;
  256. case ExpressionKind::IntLiteral:
  257. expression_proto.mutable_int_literal()->set_value(
  258. cast<IntLiteral>(expression).value());
  259. break;
  260. case ExpressionKind::StringLiteral:
  261. expression_proto.mutable_string_literal()->set_value(
  262. cast<StringLiteral>(expression).value());
  263. break;
  264. case ExpressionKind::StringTypeLiteral:
  265. expression_proto.mutable_string_type_literal();
  266. break;
  267. case ExpressionKind::ContinuationTypeLiteral:
  268. expression_proto.mutable_continuation_type_literal();
  269. break;
  270. case ExpressionKind::TypeTypeLiteral:
  271. expression_proto.mutable_type_type_literal();
  272. break;
  273. case ExpressionKind::UnimplementedExpression:
  274. expression_proto.mutable_unimplemented_expression();
  275. break;
  276. case ExpressionKind::ArrayTypeLiteral: {
  277. const auto& array_literal = cast<ArrayTypeLiteral>(expression);
  278. Fuzzing::ArrayTypeLiteral* array_literal_proto =
  279. expression_proto.mutable_array_type_literal();
  280. *array_literal_proto->mutable_element_type() =
  281. ExpressionToProto(array_literal.element_type_expression());
  282. *array_literal_proto->mutable_size() =
  283. ExpressionToProto(array_literal.size_expression());
  284. break;
  285. }
  286. }
  287. return expression_proto;
  288. }
  289. static auto BindingPatternToProto(const BindingPattern& pattern)
  290. -> Fuzzing::BindingPattern {
  291. Fuzzing::BindingPattern pattern_proto;
  292. pattern_proto.set_name(pattern.name());
  293. *pattern_proto.mutable_type() = PatternToProto(pattern.type());
  294. return pattern_proto;
  295. }
  296. static auto GenericBindingToProto(const GenericBinding& binding)
  297. -> Fuzzing::GenericBinding {
  298. Fuzzing::GenericBinding binding_proto;
  299. binding_proto.set_name(binding.name());
  300. *binding_proto.mutable_type() = ExpressionToProto(binding.type());
  301. return binding_proto;
  302. }
  303. static auto TuplePatternToProto(const TuplePattern& tuple_pattern)
  304. -> Fuzzing::TuplePattern {
  305. Fuzzing::TuplePattern tuple_pattern_proto;
  306. for (Nonnull<const Pattern*> field : tuple_pattern.fields()) {
  307. *tuple_pattern_proto.add_fields() = PatternToProto(*field);
  308. }
  309. return tuple_pattern_proto;
  310. }
  311. static auto PatternToProto(const Pattern& pattern) -> Fuzzing::Pattern {
  312. Fuzzing::Pattern pattern_proto;
  313. switch (pattern.kind()) {
  314. case PatternKind::GenericBinding: {
  315. const auto& binding = cast<GenericBinding>(pattern);
  316. *pattern_proto.mutable_generic_binding() = GenericBindingToProto(binding);
  317. break;
  318. }
  319. case PatternKind::BindingPattern: {
  320. const auto& binding = cast<BindingPattern>(pattern);
  321. *pattern_proto.mutable_binding_pattern() = BindingPatternToProto(binding);
  322. break;
  323. }
  324. case PatternKind::TuplePattern:
  325. *pattern_proto.mutable_tuple_pattern() =
  326. TuplePatternToProto(cast<TuplePattern>(pattern));
  327. break;
  328. case PatternKind::AlternativePattern: {
  329. const auto& alternative = cast<AlternativePattern>(pattern);
  330. auto* alternative_proto = pattern_proto.mutable_alternative_pattern();
  331. alternative_proto->set_alternative_name(alternative.alternative_name());
  332. *alternative_proto->mutable_choice_type() =
  333. ExpressionToProto(alternative.choice_type());
  334. *alternative_proto->mutable_arguments() =
  335. TuplePatternToProto(alternative.arguments());
  336. break;
  337. }
  338. case PatternKind::ExpressionPattern:
  339. *pattern_proto.mutable_expression_pattern()->mutable_expression() =
  340. ExpressionToProto(cast<ExpressionPattern>(pattern).expression());
  341. break;
  342. case PatternKind::AutoPattern:
  343. pattern_proto.mutable_auto_pattern();
  344. break;
  345. case PatternKind::VarPattern:
  346. *pattern_proto.mutable_var_pattern()->mutable_pattern() =
  347. PatternToProto(cast<VarPattern>(pattern).pattern());
  348. break;
  349. case PatternKind::AddrPattern:
  350. *pattern_proto.mutable_addr_pattern()->mutable_binding_pattern() =
  351. BindingPatternToProto(cast<AddrPattern>(pattern).binding());
  352. break;
  353. }
  354. return pattern_proto;
  355. }
  356. static auto BlockStatementToProto(const Block& block)
  357. -> Fuzzing::BlockStatement {
  358. Fuzzing::BlockStatement block_proto;
  359. for (Nonnull<const Statement*> statement : block.statements()) {
  360. *block_proto.add_statements() = StatementToProto(*statement);
  361. }
  362. return block_proto;
  363. }
  364. static auto StatementToProto(const Statement& statement) -> Fuzzing::Statement {
  365. Fuzzing::Statement statement_proto;
  366. switch (statement.kind()) {
  367. case StatementKind::ExpressionStatement:
  368. *statement_proto.mutable_expression_statement()->mutable_expression() =
  369. ExpressionToProto(cast<ExpressionStatement>(statement).expression());
  370. break;
  371. case StatementKind::Assign: {
  372. const auto& assign = cast<Assign>(statement);
  373. auto* assign_proto = statement_proto.mutable_assign();
  374. *assign_proto->mutable_lhs() = ExpressionToProto(assign.lhs());
  375. *assign_proto->mutable_rhs() = ExpressionToProto(assign.rhs());
  376. break;
  377. }
  378. case StatementKind::VariableDefinition: {
  379. const auto& def = cast<VariableDefinition>(statement);
  380. auto* def_proto = statement_proto.mutable_variable_definition();
  381. *def_proto->mutable_pattern() = PatternToProto(def.pattern());
  382. if (def.has_init()) {
  383. *def_proto->mutable_init() = ExpressionToProto(def.init());
  384. }
  385. def_proto->set_is_returned(def.is_returned());
  386. break;
  387. }
  388. case StatementKind::If: {
  389. const auto& if_stmt = cast<If>(statement);
  390. auto* if_proto = statement_proto.mutable_if_statement();
  391. *if_proto->mutable_condition() = ExpressionToProto(if_stmt.condition());
  392. *if_proto->mutable_then_block() =
  393. BlockStatementToProto(if_stmt.then_block());
  394. if (if_stmt.else_block().has_value()) {
  395. *if_proto->mutable_else_block() =
  396. BlockStatementToProto(**if_stmt.else_block());
  397. }
  398. break;
  399. }
  400. case StatementKind::ReturnVar: {
  401. statement_proto.mutable_return_var_statement();
  402. break;
  403. }
  404. case StatementKind::ReturnExpression: {
  405. const auto& ret = cast<ReturnExpression>(statement);
  406. auto* ret_proto = statement_proto.mutable_return_expression_statement();
  407. if (!ret.is_omitted_expression()) {
  408. *ret_proto->mutable_expression() = ExpressionToProto(ret.expression());
  409. } else {
  410. ret_proto->set_is_omitted_expression(true);
  411. }
  412. break;
  413. }
  414. case StatementKind::Block:
  415. *statement_proto.mutable_block() =
  416. BlockStatementToProto(cast<Block>(statement));
  417. break;
  418. case StatementKind::While: {
  419. const auto& while_stmt = cast<While>(statement);
  420. auto* while_proto = statement_proto.mutable_while_statement();
  421. *while_proto->mutable_condition() =
  422. ExpressionToProto(while_stmt.condition());
  423. *while_proto->mutable_body() = BlockStatementToProto(while_stmt.body());
  424. break;
  425. }
  426. case StatementKind::Match: {
  427. const auto& match = cast<Match>(statement);
  428. auto* match_proto = statement_proto.mutable_match();
  429. *match_proto->mutable_expression() =
  430. ExpressionToProto(match.expression());
  431. for (const Match::Clause& clause : match.clauses()) {
  432. auto* clause_proto = match_proto->add_clauses();
  433. // TODO: Working out whether we have a default clause after the fact
  434. // like this is fragile.
  435. bool is_default_clause = false;
  436. if (auto* binding = dyn_cast<BindingPattern>(&clause.pattern())) {
  437. if (binding->name() == AnonymousName &&
  438. isa<AutoPattern>(binding->type()) &&
  439. binding->source_loc() == binding->type().source_loc()) {
  440. is_default_clause = true;
  441. }
  442. }
  443. if (is_default_clause) {
  444. clause_proto->set_is_default(true);
  445. } else {
  446. *clause_proto->mutable_pattern() = PatternToProto(clause.pattern());
  447. }
  448. *clause_proto->mutable_statement() =
  449. StatementToProto(clause.statement());
  450. }
  451. break;
  452. }
  453. case StatementKind::Continuation: {
  454. const auto& continuation = cast<Continuation>(statement);
  455. auto* continuation_proto = statement_proto.mutable_continuation();
  456. continuation_proto->set_name(continuation.name());
  457. *continuation_proto->mutable_body() =
  458. BlockStatementToProto(continuation.body());
  459. break;
  460. }
  461. case StatementKind::Run:
  462. *statement_proto.mutable_run()->mutable_argument() =
  463. ExpressionToProto(cast<Run>(statement).argument());
  464. break;
  465. case StatementKind::Await:
  466. // Initializes with the default value; there's nothing to set.
  467. statement_proto.mutable_await_statement();
  468. break;
  469. case StatementKind::Break:
  470. // Initializes with the default value; there's nothing to set.
  471. statement_proto.mutable_break_statement();
  472. break;
  473. case StatementKind::Continue:
  474. // Initializes with the default value; there's nothing to set.
  475. statement_proto.mutable_continue_statement();
  476. break;
  477. case StatementKind::For: {
  478. const auto& for_stmt = cast<For>(statement);
  479. auto* for_proto = statement_proto.mutable_for_statement();
  480. *for_proto->mutable_var_decl() =
  481. BindingPatternToProto(for_stmt.variable_declaration());
  482. *for_proto->mutable_target() = ExpressionToProto(for_stmt.loop_target());
  483. *for_proto->mutable_body() = BlockStatementToProto(for_stmt.body());
  484. break;
  485. }
  486. }
  487. return statement_proto;
  488. }
  489. static auto ReturnTermToProto(const ReturnTerm& return_term)
  490. -> Fuzzing::ReturnTerm {
  491. Fuzzing::ReturnTerm return_term_proto;
  492. if (return_term.is_omitted()) {
  493. return_term_proto.set_kind(Fuzzing::ReturnTerm::Omitted);
  494. } else if (return_term.is_auto()) {
  495. return_term_proto.set_kind(Fuzzing::ReturnTerm::Auto);
  496. } else {
  497. return_term_proto.set_kind(Fuzzing::ReturnTerm::Expression);
  498. *return_term_proto.mutable_type() =
  499. ExpressionToProto(**return_term.type_expression());
  500. }
  501. return return_term_proto;
  502. }
  503. static auto DeclarationToProto(const Declaration& declaration)
  504. -> Fuzzing::Declaration {
  505. Fuzzing::Declaration declaration_proto;
  506. switch (declaration.kind()) {
  507. case DeclarationKind::FunctionDeclaration: {
  508. const auto& function = cast<FunctionDeclaration>(declaration);
  509. auto* function_proto = declaration_proto.mutable_function();
  510. function_proto->set_name(function.name());
  511. for (Nonnull<const GenericBinding*> binding :
  512. function.deduced_parameters()) {
  513. *function_proto->add_deduced_parameters() =
  514. GenericBindingToProto(*binding);
  515. }
  516. if (function.is_method()) {
  517. switch (function.me_pattern().kind()) {
  518. case PatternKind::AddrPattern:
  519. *function_proto->mutable_me_pattern() =
  520. PatternToProto(cast<AddrPattern>(function.me_pattern()));
  521. break;
  522. case PatternKind::BindingPattern:
  523. *function_proto->mutable_me_pattern() =
  524. PatternToProto(cast<BindingPattern>(function.me_pattern()));
  525. break;
  526. default:
  527. // Parser shouldn't allow me_pattern to be anything other than
  528. // AddrPattern or BindingPattern
  529. CARBON_FATAL() << "me_pattern in method declaration can be either "
  530. "AddrPattern or BindingPattern. Actual pattern: "
  531. << function.me_pattern();
  532. break;
  533. }
  534. }
  535. *function_proto->mutable_param_pattern() =
  536. TuplePatternToProto(function.param_pattern());
  537. *function_proto->mutable_return_term() =
  538. ReturnTermToProto(function.return_term());
  539. if (function.body().has_value()) {
  540. *function_proto->mutable_body() =
  541. BlockStatementToProto(**function.body());
  542. }
  543. break;
  544. }
  545. case DeclarationKind::ClassDeclaration: {
  546. const auto& class_decl = cast<ClassDeclaration>(declaration);
  547. auto* class_proto = declaration_proto.mutable_class_declaration();
  548. class_proto->set_name(class_decl.name());
  549. if (class_decl.type_params().has_value()) {
  550. *class_proto->mutable_type_params() =
  551. TuplePatternToProto(**class_decl.type_params());
  552. }
  553. for (Nonnull<const Declaration*> member : class_decl.members()) {
  554. *class_proto->add_members() = DeclarationToProto(*member);
  555. }
  556. break;
  557. }
  558. case DeclarationKind::MixinDeclaration: {
  559. const auto& mixin = cast<MixinDeclaration>(declaration);
  560. auto* mixin_proto = declaration_proto.mutable_mixin();
  561. mixin_proto->set_name(mixin.name());
  562. for (const auto& member : mixin.members()) {
  563. *mixin_proto->add_members() = DeclarationToProto(*member);
  564. }
  565. // Type params not implemented yet
  566. // if (mixin.params().has_value()) {
  567. // *mixin_proto->mutable_params() =
  568. // TuplePatternToProto(**mixin.params());
  569. //}
  570. *mixin_proto->mutable_self() = GenericBindingToProto(*mixin.self());
  571. break;
  572. }
  573. case DeclarationKind::MixDeclaration: {
  574. const auto& mix = cast<MixDeclaration>(declaration);
  575. auto* mix_proto = declaration_proto.mutable_mix();
  576. *mix_proto->mutable_mixin() = ExpressionToProto(mix.mixin());
  577. break;
  578. }
  579. case DeclarationKind::ChoiceDeclaration: {
  580. const auto& choice = cast<ChoiceDeclaration>(declaration);
  581. auto* choice_proto = declaration_proto.mutable_choice();
  582. choice_proto->set_name(choice.name());
  583. for (Nonnull<const AlternativeSignature*> alternative :
  584. choice.alternatives()) {
  585. auto* alternative_proto = choice_proto->add_alternatives();
  586. alternative_proto->set_name(alternative->name());
  587. *alternative_proto->mutable_signature() =
  588. TupleLiteralExpressionToProto(alternative->signature());
  589. }
  590. break;
  591. }
  592. case DeclarationKind::VariableDeclaration: {
  593. const auto& var = cast<VariableDeclaration>(declaration);
  594. auto* var_proto = declaration_proto.mutable_variable();
  595. *var_proto->mutable_binding() = BindingPatternToProto(var.binding());
  596. if (var.has_initializer()) {
  597. *var_proto->mutable_initializer() =
  598. ExpressionToProto(var.initializer());
  599. }
  600. break;
  601. }
  602. case DeclarationKind::AssociatedConstantDeclaration: {
  603. const auto& assoc = cast<AssociatedConstantDeclaration>(declaration);
  604. auto* let_proto = declaration_proto.mutable_let();
  605. *let_proto->mutable_pattern() = PatternToProto(assoc.binding());
  606. break;
  607. }
  608. case DeclarationKind::InterfaceDeclaration: {
  609. const auto& interface = cast<InterfaceDeclaration>(declaration);
  610. auto* interface_proto = declaration_proto.mutable_interface();
  611. interface_proto->set_name(interface.name());
  612. for (const auto& member : interface.members()) {
  613. *interface_proto->add_members() = DeclarationToProto(*member);
  614. }
  615. *interface_proto->mutable_self() =
  616. GenericBindingToProto(*interface.self());
  617. break;
  618. }
  619. case DeclarationKind::ImplDeclaration: {
  620. const auto& impl = cast<ImplDeclaration>(declaration);
  621. auto* impl_proto = declaration_proto.mutable_impl();
  622. switch (impl.kind()) {
  623. case ImplKind::InternalImpl:
  624. impl_proto->set_kind(Fuzzing::ImplDeclaration::InternalImpl);
  625. break;
  626. case ImplKind::ExternalImpl:
  627. impl_proto->set_kind(Fuzzing::ImplDeclaration::ExternalImpl);
  628. break;
  629. }
  630. *impl_proto->mutable_impl_type() = ExpressionToProto(*impl.impl_type());
  631. *impl_proto->mutable_interface() = ExpressionToProto(impl.interface());
  632. for (const auto& member : impl.members()) {
  633. *impl_proto->add_members() = DeclarationToProto(*member);
  634. }
  635. break;
  636. }
  637. case DeclarationKind::SelfDeclaration: {
  638. CARBON_FATAL() << "Unreachable SelfDeclaration in DeclarationToProto().";
  639. }
  640. case DeclarationKind::AliasDeclaration: {
  641. const auto& alias = cast<AliasDeclaration>(declaration);
  642. auto* alias_proto = declaration_proto.mutable_alias();
  643. alias_proto->set_name(alias.name());
  644. *alias_proto->mutable_target() = ExpressionToProto(alias.target());
  645. break;
  646. }
  647. }
  648. return declaration_proto;
  649. }
  650. Fuzzing::CompilationUnit AstToProto(const AST& ast) {
  651. Fuzzing::CompilationUnit compilation_unit;
  652. *compilation_unit.mutable_package_statement() =
  653. LibraryNameToProto(ast.package);
  654. compilation_unit.set_is_api(ast.is_api);
  655. for (const Declaration* declaration : ast.declarations) {
  656. *compilation_unit.add_declarations() = DeclarationToProto(*declaration);
  657. }
  658. return compilation_unit;
  659. }
  660. } // namespace Carbon