pw_rpc: Method union class

This adds a MethodUnion class which can store one of multiple
method types, and updates the base Service class to store them instead
of concrete Methods. A MethodUnion class for raw methods and for
nanopb/raw methods is added to the respective submodules. Also, the
nanopb codegen API and script are updated to deduce a method type from
an implementation's signature, and create the invoker automatically.

This does not update the TestMethodContext class to work with the new
changes; tests depending on it are temporarily disabled until fixed.

Change-Id: I982662fb2b022323c8df293bf34d5fca9a8d91c0
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/21242
Reviewed-by: Wyatt Hepler <hepler@google.com>
diff --git a/pw_rpc/service_test.cc b/pw_rpc/service_test.cc
index 107ad78..959323f 100644
--- a/pw_rpc/service_test.cc
+++ b/pw_rpc/service_test.cc
@@ -40,25 +40,39 @@
   char value;  // Add a member so the class is larger than the base Method.
 };
 
+class ServiceTestMethodUnion : public internal::MethodUnion {
+ public:
+  constexpr ServiceTestMethodUnion(ServiceTestMethod&& method)
+      : impl_({.service_test = method}) {}
+
+  constexpr const internal::Method& method() const { return impl_.method; }
+
+ private:
+  union {
+    internal::Method method;
+    ServiceTestMethod service_test;
+  } impl_;
+};
+
 class TestService : public Service {
  public:
   constexpr TestService() : Service(0xabcd, kMethods) {}
 
-  static constexpr std::array<ServiceTestMethod, 3> kMethods = {{
+  static constexpr std::array<ServiceTestMethodUnion, 3> kMethods = {
       ServiceTestMethod(123, 'a'),
       ServiceTestMethod(456, 'b'),
       ServiceTestMethod(789, 'c'),
-  }};
+  };
 };
 
 TEST(Service, MultipleMethods_FindMethod_Present) {
   TestService service;
   EXPECT_EQ(ServiceTestHelper::FindMethod(service, 123),
-            &TestService::kMethods[0]);
+            &TestService::kMethods[0].method());
   EXPECT_EQ(ServiceTestHelper::FindMethod(service, 456),
-            &TestService::kMethods[1]);
+            &TestService::kMethods[1].method());
   EXPECT_EQ(ServiceTestHelper::FindMethod(service, 789),
-            &TestService::kMethods[2]);
+            &TestService::kMethods[2].method());
 }
 
 TEST(Service, MultipleMethods_FindMethod_NotPresent) {
@@ -71,7 +85,7 @@
 class EmptyTestService : public Service {
  public:
   constexpr EmptyTestService() : Service(0xabcd, kMethods) {}
-  static constexpr std::array<ServiceTestMethod, 0> kMethods = {{}};
+  static constexpr std::array<ServiceTestMethodUnion, 0> kMethods = {};
 };
 
 TEST(Service, NoMethods_FindMethod_NotPresent) {