pw_system: Add user-specified protos to console entry point

Adds a mechanism for users of pw-system-console to inject compiled
protos into an invocation of pw-system-console when using their own
python program's main() entrypoint as a trivial wrapper around
pw_system.console.main()

This is useful for pw_system users who have some custom RPC services,
but do not (yet) need a fully-forked console implementation.

Bug: pwbug/647

Change-Id: If21f999a41dfc76a8a271e653565ab4d1b4f3e34
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/90500
Reviewed-by: Keir Mierle <keir@google.com>
Commit-Queue: Keir Mierle <keir@google.com>
diff --git a/pw_system/py/pw_system/console.py b/pw_system/py/pw_system/console.py
index 7843837..f38b569 100644
--- a/pw_system/py/pw_system/console.py
+++ b/pw_system/py/pw_system/console.py
@@ -206,6 +206,7 @@
         return self.socket.recv(num_bytes)
 
 
+#pylint: disable=too-many-arguments
 def console(device: str,
             baudrate: int,
             proto_globs: Collection[str],
@@ -215,7 +216,8 @@
             output: Any,
             serial_debug: bool = False,
             config_file: Optional[Path] = None,
-            verbose: bool = False) -> int:
+            verbose: bool = False,
+            compiled_protos: Optional[List[ModuleType]] = None) -> int:
     """Starts an interactive RPC console for HDLC."""
     # argparse.FileType doesn't correctly handle '-' for binary files.
     if output is sys.stdout:
@@ -241,10 +243,14 @@
 
     protos: List[Union[ModuleType, Path]] = list(_expand_globs(proto_globs))
 
+    if compiled_protos is None:
+        compiled_protos = []
+
     # Append compiled log.proto library to avoid include errors when manually
     # provided, and shadowing errors due to ordering when the default global
     # search path is used.
-    protos.append(log_pb2)
+    compiled_protos.append(log_pb2)
+    protos.extend(compiled_protos)
 
     if not protos:
         _LOG.critical('No .proto files were found with %s',
@@ -300,5 +306,9 @@
     return console(**vars(_parse_args()))
 
 
+def main_with_compiled_protos(compiled_protos):
+    return console(**vars(_parse_args()), compiled_protos=compiled_protos)
+
+
 if __name__ == '__main__':
     sys.exit(main())