ast_to_proto.cpp 25 KB

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