pw_rpc: Support cross-module request and response types
- Load request and response protos from their own files instead of
assuming they're defined in the same module.
- Don't invoke protoc if no proto file paths are provided.
Change-Id: I44ceedf0ddcb0751368d41d75de3316cf21c34f2
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/26740
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Alexei Frolov <frolv@google.com>
diff --git a/pw_protobuf_compiler/py/pw_protobuf_compiler/python_protos.py b/pw_protobuf_compiler/py/pw_protobuf_compiler/python_protos.py
index 3286ccc..e43a7cf 100644
--- a/pw_protobuf_compiler/py/pw_protobuf_compiler/python_protos.py
+++ b/pw_protobuf_compiler/py/pw_protobuf_compiler/python_protos.py
@@ -259,7 +259,8 @@
else:
modules.append(proto)
- modules += compile_and_import(paths)
+ if paths:
+ modules += compile_and_import(paths)
return Library(modules)
@classmethod
diff --git a/pw_rpc/py/pw_rpc/client.py b/pw_rpc/py/pw_rpc/client.py
index 3624989..3661214 100644
--- a/pw_rpc/py/pw_rpc/client.py
+++ b/pw_rpc/py/pw_rpc/client.py
@@ -280,7 +280,7 @@
modules: Iterable):
return cls(
impl, channels,
- (Service.from_descriptor(module, service) for module in modules
+ (Service.from_descriptor(service) for module in modules
for service in module.DESCRIPTOR.services_by_name.values()))
def __init__(self, impl: ClientImpl, channels: Iterable[Channel],
diff --git a/pw_rpc/py/pw_rpc/descriptors.py b/pw_rpc/py/pw_rpc/descriptors.py
index 03ae62b..7ac7af1 100644
--- a/pw_rpc/py/pw_rpc/descriptors.py
+++ b/pw_rpc/py/pw_rpc/descriptors.py
@@ -19,7 +19,7 @@
from typing import (Any, Callable, Collection, Dict, Generic, Iterable,
Iterator, Tuple, TypeVar, Union)
-from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor_pb2, message_factory
from google.protobuf.descriptor import FieldDescriptor
from pw_protobuf_compiler import python_protos
@@ -48,13 +48,13 @@
return f'{self.package}.{self.name}'
@classmethod
- def from_descriptor(cls, module, descriptor):
+ def from_descriptor(cls, descriptor):
service = cls(descriptor.name, ids.calculate(descriptor.full_name),
descriptor.file.package, None)
object.__setattr__(
service, 'methods',
Methods(
- Method.from_descriptor(module, method_descriptor, service)
+ Method.from_descriptor(method_descriptor, service)
for method_descriptor in descriptor.methods))
return service
@@ -124,14 +124,18 @@
response_type: Any
@classmethod
- def from_descriptor(cls, module, descriptor, service: Service):
+ def from_descriptor(cls, descriptor, service: Service):
+ input_factory = message_factory.MessageFactory(
+ descriptor.input_type.file.pool)
+ output_factory = message_factory.MessageFactory(
+ descriptor.output_type.file.pool)
return Method(
service,
descriptor.name,
ids.calculate(descriptor.name),
*_streaming_attributes(descriptor),
- getattr(module, descriptor.input_type.name),
- getattr(module, descriptor.output_type.name),
+ input_factory.GetPrototype(descriptor.input_type),
+ output_factory.GetPrototype(descriptor.output_type),
)
class Type(enum.Enum):