| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  |  *    list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |  *    this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |  *    and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
					
						
							|  |  |  |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
					
						
							|  |  |  |  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
					
						
							|  |  |  |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 22:29:06 +01:00
										 |  |  | #include <AK/Function.h>
 | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  | #include <AK/GenericLexer.h>
 | 
					
						
							| 
									
										
										
										
											2019-08-03 16:18:37 +02:00
										 |  |  | #include <AK/HashMap.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | #include <AK/SourceGenerator.h>
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  | #include <AK/StringBuilder.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-06 15:04:03 +01:00
										 |  |  | #include <LibCore/File.h>
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-02 09:33:37 +01:00
										 |  |  | //#define GENERATE_DEBUG_CODE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  | struct Parameter { | 
					
						
							| 
									
										
										
										
											2020-05-16 14:11:35 +02:00
										 |  |  |     Vector<String> attributes; | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |     String type; | 
					
						
							|  |  |  |     String name; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct Message { | 
					
						
							|  |  |  |     String name; | 
					
						
							|  |  |  |     bool is_synchronous { false }; | 
					
						
							|  |  |  |     Vector<Parameter> inputs; | 
					
						
							|  |  |  |     Vector<Parameter> outputs; | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     String response_name() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         StringBuilder builder; | 
					
						
							|  |  |  |         builder.append(name); | 
					
						
							|  |  |  |         builder.append("Response"); | 
					
						
							|  |  |  |         return builder.to_string(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct Endpoint { | 
					
						
							|  |  |  |     String name; | 
					
						
							| 
									
										
										
										
											2019-11-23 16:43:21 +01:00
										 |  |  |     int magic; | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |     Vector<Message> messages; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char** argv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (argc != 2) { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         outln("usage: {} <IPC endpoint definition file>", argv[0]); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 12:34:39 +01:00
										 |  |  |     auto file = Core::File::construct(argv[1]); | 
					
						
							|  |  |  |     if (!file->open(Core::IODevice::ReadOnly)) { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         warnln("Error: Cannot open {}: {}", argv[1], file->error_string()); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-21 20:50:06 +02:00
										 |  |  |     auto file_contents = file->read_all(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |     GenericLexer lexer(file_contents); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Vector<Endpoint> endpoints; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |     auto assert_specific = [&](char ch) { | 
					
						
							|  |  |  |         if (lexer.peek() != ch) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |             warnln("assert_specific: wanted '{}', but got '{}' at index {}", ch, lexer.peek(), lexer.tell()); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         bool saw_expected = lexer.consume_specific(ch); | 
					
						
							|  |  |  |         ASSERT(saw_expected); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto consume_whitespace = [&] { | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         lexer.ignore_while([](char ch) { return isspace(ch); }); | 
					
						
							|  |  |  |         if (lexer.peek() == '/' && lexer.peek(1) == '/') | 
					
						
							|  |  |  |             lexer.ignore_until([](char ch) { return ch == '\n'; }); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto parse_parameter = [&](Vector<Parameter>& storage) { | 
					
						
							|  |  |  |         for (;;) { | 
					
						
							|  |  |  |             Parameter parameter; | 
					
						
							|  |  |  |             consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             if (lexer.peek() == ')') | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             if (lexer.consume_specific('[')) { | 
					
						
							| 
									
										
										
										
											2020-05-16 14:11:35 +02:00
										 |  |  |                 for (;;) { | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |                     if (lexer.consume_specific(']')) { | 
					
						
							| 
									
										
										
										
											2020-05-16 14:11:35 +02:00
										 |  |  |                         consume_whitespace(); | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |                     if (lexer.consume_specific(',')) { | 
					
						
							| 
									
										
										
										
											2020-05-16 14:11:35 +02:00
										 |  |  |                         consume_whitespace(); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |                     auto attribute = lexer.consume_until([](char ch) { return ch == ']' || ch == ','; }); | 
					
						
							| 
									
										
										
										
											2020-05-16 14:11:35 +02:00
										 |  |  |                     parameter.attributes.append(attribute); | 
					
						
							|  |  |  |                     consume_whitespace(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             parameter.type = lexer.consume_until([](char ch) { return isspace(ch); }); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |             consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             parameter.name = lexer.consume_until([](char ch) { return isspace(ch) || ch == ',' || ch == ')'; }); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |             consume_whitespace(); | 
					
						
							|  |  |  |             storage.append(move(parameter)); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             if (lexer.consume_specific(',')) | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 continue; | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             if (lexer.peek() == ')') | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto parse_parameters = [&](Vector<Parameter>& storage) { | 
					
						
							|  |  |  |         for (;;) { | 
					
						
							|  |  |  |             consume_whitespace(); | 
					
						
							|  |  |  |             parse_parameter(storage); | 
					
						
							|  |  |  |             consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             if (lexer.consume_specific(',')) | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 continue; | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             if (lexer.peek() == ')') | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto parse_message = [&] { | 
					
						
							|  |  |  |         Message message; | 
					
						
							|  |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         message.name = lexer.consume_until([](char ch) { return isspace(ch) || ch == '('; }); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         assert_specific('('); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         parse_parameters(message.inputs); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         assert_specific(')'); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         assert_specific('='); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         auto type = lexer.consume(); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         if (type == '>') | 
					
						
							|  |  |  |             message.is_synchronous = true; | 
					
						
							|  |  |  |         else if (type == '|') | 
					
						
							|  |  |  |             message.is_synchronous = false; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             ASSERT_NOT_REACHED(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         consume_whitespace(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (message.is_synchronous) { | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             assert_specific('('); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |             parse_parameters(message.outputs); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             assert_specific(')'); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         consume_whitespace(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         endpoints.last().messages.append(move(message)); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto parse_messages = [&] { | 
					
						
							|  |  |  |         for (;;) { | 
					
						
							|  |  |  |             consume_whitespace(); | 
					
						
							|  |  |  |             parse_message(); | 
					
						
							|  |  |  |             consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |             if (lexer.peek() == '}') | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto parse_endpoint = [&] { | 
					
						
							|  |  |  |         endpoints.empend(); | 
					
						
							|  |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         lexer.consume_specific("endpoint"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         endpoints.last().name = lexer.consume_while([](char ch) { return !isspace(ch); }); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         assert_specific('='); | 
					
						
							| 
									
										
										
										
											2019-11-23 16:43:21 +01:00
										 |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         auto magic_string = lexer.consume_while([](char ch) { return !isspace(ch) && ch != '{'; }); | 
					
						
							| 
									
										
										
										
											2020-06-12 21:07:52 +02:00
										 |  |  |         endpoints.last().magic = magic_string.to_int().value(); | 
					
						
							| 
									
										
										
										
											2019-11-23 16:43:21 +01:00
										 |  |  |         consume_whitespace(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         assert_specific('{'); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         parse_messages(); | 
					
						
							| 
									
										
										
										
											2020-08-21 09:18:10 -04:00
										 |  |  |         assert_specific('}'); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         consume_whitespace(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-21 10:39:46 -04:00
										 |  |  |     while (lexer.tell() < file_contents.size()) | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         parse_endpoint(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     SourceGenerator generator { builder }; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     generator.append(R"~~~( | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | #include <AK/MemoryStream.h>
 | 
					
						
							|  |  |  | #include <AK/OwnPtr.h>
 | 
					
						
							|  |  |  | #include <AK/URL.h>
 | 
					
						
							|  |  |  | #include <AK/Utf8View.h>
 | 
					
						
							|  |  |  | #include <LibGfx/Color.h>
 | 
					
						
							|  |  |  | #include <LibGfx/Rect.h>
 | 
					
						
							|  |  |  | #include <LibGfx/ShareableBitmap.h>
 | 
					
						
							|  |  |  | #include <LibIPC/Decoder.h>
 | 
					
						
							|  |  |  | #include <LibIPC/Dictionary.h>
 | 
					
						
							|  |  |  | #include <LibIPC/Encoder.h>
 | 
					
						
							|  |  |  | #include <LibIPC/Endpoint.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-21 21:59:12 +03:00
										 |  |  | #include <LibIPC/File.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | #include <LibIPC/Message.h>
 | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (auto& endpoint : endpoints) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |         auto endpoint_generator = generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         endpoint_generator.set("endpoint.name", endpoint.name); | 
					
						
							|  |  |  |         endpoint_generator.set("endpoint.magic", String::number(endpoint.magic)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  | namespace Messages::@endpoint.name@ { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 16:18:37 +02:00
										 |  |  |         HashMap<String, int> message_ids; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  | enum class MessageID : i32 { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 16:18:37 +02:00
										 |  |  |         for (auto& message : endpoint.messages) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |             auto message_generator = endpoint_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 16:18:37 +02:00
										 |  |  |             message_ids.set(message.name, message_ids.size() + 1); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |             message_generator.set("message.name", message.name); | 
					
						
							|  |  |  |             message_generator.set("message.id", String::number(message_ids.size())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  |     @message.name@ = @message.id@, | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 16:18:37 +02:00
										 |  |  |             if (message.is_synchronous) { | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  |                 message_ids.set(message.response_name(), message_ids.size() + 1); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                 message_generator.set("message.name", message.response_name()); | 
					
						
							|  |  |  |                 message_generator.set("message.id", String::number(message_ids.size())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 message_generator.append(R"~~~( | 
					
						
							|  |  |  |     @message.name@ = @message.id@, | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 16:18:37 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 16:18:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 16:35:49 +02:00
										 |  |  |         auto constructor_for_message = [&](const String& name, const Vector<Parameter>& parameters) { | 
					
						
							|  |  |  |             StringBuilder builder; | 
					
						
							|  |  |  |             builder.append(name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (parameters.is_empty()) { | 
					
						
							|  |  |  |                 builder.append("() {}"); | 
					
						
							|  |  |  |                 return builder.to_string(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             builder.append('('); | 
					
						
							| 
									
										
										
										
											2020-02-25 14:49:47 +01:00
										 |  |  |             for (size_t i = 0; i < parameters.size(); ++i) { | 
					
						
							| 
									
										
										
										
											2019-08-03 16:35:49 +02:00
										 |  |  |                 auto& parameter = parameters[i]; | 
					
						
							| 
									
										
										
										
											2019-12-14 16:15:14 +01:00
										 |  |  |                 builder.append("const "); | 
					
						
							| 
									
										
										
										
											2019-08-03 16:35:49 +02:00
										 |  |  |                 builder.append(parameter.type); | 
					
						
							| 
									
										
										
										
											2019-12-14 16:15:14 +01:00
										 |  |  |                 builder.append("& "); | 
					
						
							| 
									
										
										
										
											2019-08-03 16:35:49 +02:00
										 |  |  |                 builder.append(parameter.name); | 
					
						
							|  |  |  |                 if (i != parameters.size() - 1) | 
					
						
							|  |  |  |                     builder.append(", "); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             builder.append(") : "); | 
					
						
							| 
									
										
										
										
											2020-02-25 14:49:47 +01:00
										 |  |  |             for (size_t i = 0; i < parameters.size(); ++i) { | 
					
						
							| 
									
										
										
										
											2019-08-03 16:35:49 +02:00
										 |  |  |                 auto& parameter = parameters[i]; | 
					
						
							|  |  |  |                 builder.append("m_"); | 
					
						
							|  |  |  |                 builder.append(parameter.name); | 
					
						
							|  |  |  |                 builder.append("("); | 
					
						
							|  |  |  |                 builder.append(parameter.name); | 
					
						
							|  |  |  |                 builder.append(")"); | 
					
						
							|  |  |  |                 if (i != parameters.size() - 1) | 
					
						
							|  |  |  |                     builder.append(", "); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             builder.append(" {}"); | 
					
						
							|  |  |  |             return builder.to_string(); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 16:43:21 +01:00
										 |  |  |         auto do_message = [&](const String& name, const Vector<Parameter>& parameters, const String& response_type = {}) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |             auto message_generator = endpoint_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |             message_generator.set("message.name", name); | 
					
						
							|  |  |  |             message_generator.set("message.response_type", response_type); | 
					
						
							|  |  |  |             message_generator.set("message.constructor", constructor_for_message(name, parameters)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  | class @message.name@ final : public IPC::Message { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 16:05:53 +02:00
										 |  |  |             if (!response_type.is_null()) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                 message_generator.append(R"~~~( | 
					
						
							|  |  |  |    typedef class @message.response_type@ ResponseType; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  |     @message.constructor@ | 
					
						
							|  |  |  |     virtual ~@message.name@() override {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual i32 endpoint_magic() const override { return @endpoint.magic@; } | 
					
						
							|  |  |  |     virtual i32 message_id() const override { return (int)MessageID::@message.name@; } | 
					
						
							|  |  |  |     static i32 static_message_id() { return (int)MessageID::@message.name@; } | 
					
						
							|  |  |  |     virtual const char* message_name() const override { return "@endpoint.name@::@message.name@"; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-21 21:59:12 +03:00
										 |  |  |     static OwnPtr<@message.name@> decode(InputMemoryStream& stream, int sockfd) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-11-21 21:59:12 +03:00
										 |  |  |         IPC::Decoder decoder { stream, sockfd }; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             for (auto& parameter : parameters) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |                 auto parameter_generator = message_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 parameter_generator.set("parameter.type", parameter.type); | 
					
						
							|  |  |  |                 parameter_generator.set("parameter.name", parameter.name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 17:24:47 +02:00
										 |  |  |                 if (parameter.type == "bool") | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                     parameter_generator.set("parameter.initial_value", "false"); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     parameter_generator.set("parameter.initial_value", "{}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 parameter_generator.append(R"~~~( | 
					
						
							|  |  |  |         @parameter.type@ @parameter.name@ = @parameter.initial_value@; | 
					
						
							|  |  |  |         if (!decoder.decode(@parameter.name@)) | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-16 14:11:35 +02:00
										 |  |  |                 if (parameter.attributes.contains_slow("UTF8")) { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                     parameter_generator.append(R"~~~( | 
					
						
							|  |  |  |         if (!Utf8View(@parameter.name@).validate()) | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2020-05-16 14:11:35 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             StringBuilder builder; | 
					
						
							| 
									
										
										
										
											2020-02-25 14:49:47 +01:00
										 |  |  |             for (size_t i = 0; i < parameters.size(); ++i) { | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  |                 auto& parameter = parameters[i]; | 
					
						
							|  |  |  |                 builder.append(parameter.name); | 
					
						
							|  |  |  |                 if (i != parameters.size() - 1) | 
					
						
							|  |  |  |                     builder.append(", "); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             message_generator.set("message.constructor_call_parameters", builder.build()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  |         return make<@message.name@>(@message.constructor_call_parameters@); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  |     virtual IPC::MessageBuffer encode() const override | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         IPC::MessageBuffer buffer; | 
					
						
							|  |  |  |         IPC::Encoder stream(buffer); | 
					
						
							|  |  |  |         stream << endpoint_magic(); | 
					
						
							|  |  |  |         stream << (int)MessageID::@message.name@; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 16:35:49 +02:00
										 |  |  |             for (auto& parameter : parameters) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |                 auto parameter_generator = message_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 parameter_generator.set("parameter.name", parameter.name); | 
					
						
							|  |  |  |                 parameter_generator.append(R"~~~( | 
					
						
							|  |  |  |         stream << m_@parameter.name@; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  |         return buffer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 17:24:47 +02:00
										 |  |  |             for (auto& parameter : parameters) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |                 auto parameter_generator = message_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                 parameter_generator.set("parameter.type", parameter.type); | 
					
						
							|  |  |  |                 parameter_generator.set("parameter.name", parameter.name); | 
					
						
							|  |  |  |                 parameter_generator.append(R"~~~( | 
					
						
							|  |  |  |     const @parameter.type@& @parameter.name@() const { return m_@parameter.name@; } | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 17:24:47 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |             )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |             for (auto& parameter : parameters) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |                 auto parameter_generator = message_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                 parameter_generator.set("parameter.type", parameter.type); | 
					
						
							|  |  |  |                 parameter_generator.set("parameter.name", parameter.name); | 
					
						
							|  |  |  |                 parameter_generator.append(R"~~~( | 
					
						
							|  |  |  |     @parameter.type@ m_@parameter.name@; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  |             )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |         }; | 
					
						
							|  |  |  |         for (auto& message : endpoint.messages) { | 
					
						
							| 
									
										
										
										
											2019-08-03 16:05:53 +02:00
										 |  |  |             String response_name; | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |             if (message.is_synchronous) { | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  |                 response_name = message.response_name(); | 
					
						
							| 
									
										
										
										
											2019-08-03 16:05:53 +02:00
										 |  |  |                 do_message(response_name, message.outputs); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-08-03 16:05:53 +02:00
										 |  |  |             do_message(message.name, message.inputs, response_name); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  | } // namespace Messages::@endpoint.name@
 | 
					
						
							|  |  |  |         )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  | class @endpoint.name@Endpoint : public IPC::Endpoint { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     @endpoint.name@Endpoint() { } | 
					
						
							|  |  |  |     virtual ~@endpoint.name@Endpoint() override { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static int static_magic() { return @endpoint.magic@; } | 
					
						
							|  |  |  |     virtual int magic() const override { return @endpoint.magic@; } | 
					
						
							|  |  |  |     static String static_name() { return "@endpoint.name@"; } | 
					
						
							|  |  |  |     virtual String name() const override { return "@endpoint.name@"; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-19 11:30:02 +01:00
										 |  |  |     static OwnPtr<IPC::Message> decode_message(ReadonlyBytes buffer, int sockfd) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         InputMemoryStream stream { buffer }; | 
					
						
							|  |  |  |         i32 message_endpoint_magic = 0; | 
					
						
							|  |  |  |         stream >> message_endpoint_magic; | 
					
						
							|  |  |  |         if (stream.handle_any_error()) { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2020-06-08 14:10:53 +03:00
										 |  |  | #ifdef GENERATE_DEBUG_CODE
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  |             dbgln("Failed to read message endpoint magic"); | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2020-06-08 14:10:53 +03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (message_endpoint_magic != @endpoint.magic@) { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-12-02 09:33:37 +01:00
										 |  |  | #ifdef GENERATE_DEBUG_CODE
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  |             dbgln("Endpoint magic number message_endpoint_magic != @endpoint.magic@"); | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-12-02 09:33:37 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         i32 message_id = 0; | 
					
						
							|  |  |  |         stream >> message_id; | 
					
						
							|  |  |  |         if (stream.handle_any_error()) { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2020-06-08 14:10:53 +03:00
										 |  |  | #ifdef GENERATE_DEBUG_CODE
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  |             dbgln("Failed to read message ID"); | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2020-06-08 14:10:53 +03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         OwnPtr<IPC::Message> message; | 
					
						
							|  |  |  |         switch (message_id) { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  |         for (auto& message : endpoint.messages) { | 
					
						
							|  |  |  |             auto do_decode_message = [&](const String& name) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |                 auto message_generator = endpoint_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 message_generator.set("message.name", name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 message_generator.append(R"~~~( | 
					
						
							|  |  |  |         case (int)Messages::@endpoint.name@::MessageID::@message.name@: | 
					
						
							| 
									
										
										
										
											2020-11-21 21:59:12 +03:00
										 |  |  |             message = Messages::@endpoint.name@::@message.name@::decode(stream, sockfd); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  |             }; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 17:03:16 +02:00
										 |  |  |             do_decode_message(message.name); | 
					
						
							|  |  |  |             if (message.is_synchronous) | 
					
						
							|  |  |  |                 do_decode_message(message.response_name()); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-12-02 09:33:37 +01:00
										 |  |  | #ifdef GENERATE_DEBUG_CODE
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  |             dbgln("Failed to decode @endpoint.name@.({})", message_id); | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-12-02 09:33:37 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-04-06 10:12:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         if (stream.handle_any_error()) { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2020-06-08 14:10:53 +03:00
										 |  |  | #ifdef GENERATE_DEBUG_CODE
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  |             dbgln("Failed to read the message"); | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2020-06-08 14:10:53 +03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return message; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual OwnPtr<IPC::Message> handle(const IPC::Message& message) override | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch (message.message_id()) { | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 19:21:15 +02:00
										 |  |  |         for (auto& message : endpoint.messages) { | 
					
						
							|  |  |  |             auto do_decode_message = [&](const String& name, bool returns_something) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |                 auto message_generator = endpoint_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 message_generator.set("message.name", name); | 
					
						
							|  |  |  |                 message_generator.append(R"~~~( | 
					
						
							|  |  |  |         case (int)Messages::@endpoint.name@::MessageID::@message.name@: | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 19:21:15 +02:00
										 |  |  |                 if (returns_something) { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                     message_generator.append(R"~~~( | 
					
						
							|  |  |  |             return handle(static_cast<const Messages::@endpoint.name@::@message.name@&>(message)); | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 19:21:15 +02:00
										 |  |  |                 } else { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                     message_generator.append(R"~~~( | 
					
						
							|  |  |  |             handle(static_cast<const Messages::@endpoint.name@::@message.name@&>(message)); | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 19:21:15 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |             do_decode_message(message.name, message.is_synchronous); | 
					
						
							|  |  |  |             if (message.is_synchronous) | 
					
						
							|  |  |  |                 do_decode_message(message.response_name(), false); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2021-01-10 16:29:28 -07:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (auto& message : endpoint.messages) { | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |             auto message_generator = endpoint_generator.fork(); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             message_generator.set("message.name", message.name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |             String return_type = "void"; | 
					
						
							|  |  |  |             if (message.is_synchronous) { | 
					
						
							|  |  |  |                 StringBuilder builder; | 
					
						
							| 
									
										
										
										
											2020-02-06 20:20:44 +01:00
										 |  |  |                 builder.append("OwnPtr<Messages::"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |                 builder.append(endpoint.name); | 
					
						
							|  |  |  |                 builder.append("::"); | 
					
						
							|  |  |  |                 builder.append(message.name); | 
					
						
							|  |  |  |                 builder.append("Response"); | 
					
						
							| 
									
										
										
										
											2019-08-03 21:33:12 +02:00
										 |  |  |                 builder.append(">"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |                 return_type = builder.to_string(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |             message_generator.set("message.complex_return_type", return_type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             message_generator.append(R"~~~( | 
					
						
							|  |  |  |     virtual @message.complex_return_type@ handle(const Messages::@endpoint.name@::@message.name@&) = 0; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         endpoint_generator.append(R"~~~( | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | )~~~"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 18:36:56 +02:00
										 |  |  |     outln("{}", generator.as_string_view()); | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |     for (auto& endpoint : endpoints) { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |         warnln("Endpoint '{}' (magic: {})", endpoint.name, endpoint.magic); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |         for (auto& message : endpoint.messages) { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |             warnln("  Message: '{}'", message.name); | 
					
						
							|  |  |  |             warnln("    Sync: {}", message.is_synchronous); | 
					
						
							|  |  |  |             warnln("    Inputs:"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |             for (auto& parameter : message.inputs) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                 warnln("      Parameter: {} ({})", parameter.name, parameter.type); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |             if (message.inputs.is_empty()) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                 warnln("      (none)"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |             if (message.is_synchronous) { | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                 warnln("    Outputs:"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 for (auto& parameter : message.outputs) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                     warnln("      Parameter: {} ({})", parameter.name, parameter.type); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |                 if (message.outputs.is_empty()) | 
					
						
							| 
									
										
										
										
											2020-10-11 19:57:53 +02:00
										 |  |  |                     warnln("      (none)"); | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-08-03 15:50:16 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-08-03 15:15:11 +02:00
										 |  |  | } |