From b6628d0cc55daef5808c871d35410fa2fff07a62 Mon Sep 17 00:00:00 2001 From: Colin Alworth Date: Thu, 10 Aug 2023 16:24:55 -0500 Subject: [PATCH] Enable Bidirectional communication with custom server objects (#4226) Replaces the ObjectService.FetchObject gRPC call with one that supports multiple messages from the server to the client, and supports the client continuing to interact with the object beyond simply fetching it. This patch includes changes to the Java API for ObjectType plugins, while the Python API has already been released. Plugins are still able to be "fetch-only", meaning that they do not interact with the client beyond an initial message, and all existing plugins have been updated in this way. This is still experimental, and may undergo future breaking API changes. Also introduces a Python client for this API, allowing python clients to interact with objects on the server. This is also experimental, and subject to change. Fixes #3583 Co-authored-by: Matthew Runyon Co-authored-by: jianfengmao Co-authored-by: Devin Smith --- .gitignore | 3 +- .../python/PythonDeephavenSession.java | 5 +- .../codegen/impl/ObjectServiceAuthWiring.java | 96 ++ .../proto/deephaven/proto/object.grpc.pb.cc | 111 ++ .../proto/deephaven/proto/object.grpc.pb.h | 607 +++++++- .../client/proto/deephaven/proto/object.pb.cc | 1219 ++++++++++++++- .../client/proto/deephaven/proto/object.pb.h | 1333 ++++++++++++++++- docker/registry/python/gradle.properties | 4 +- docker/registry/server-base/gradle.properties | 2 +- docker/registry/slim-base/gradle.properties | 2 +- .../src/main/server-jetty/requirements.txt | 2 +- .../src/main/server-netty/requirements.txt | 2 +- .../io/deephaven/client/impl/SessionImpl.java | 2 +- .../io/deephaven/plugin/PluginModuleTest.java | 7 +- .../figure/FigureWidgetTranslator.java | 8 +- .../figure/FigureWidgetTypePlugin.java | 3 +- .../HierarchicalTableTypePlugin.java | 5 +- .../PartitionedTableTypePlugin.java | 5 +- .../io/deephaven/plugin/type/Exporter.java | 113 ++ .../type/ObjectCommunicationException.java | 23 + .../io/deephaven/plugin/type/ObjectType.java | 106 +- .../deephaven/plugin/type/ObjectTypeBase.java | 67 +- .../plugin/type/ObjectTypeClassBase.java | 60 +- .../main/proto/deephaven/proto/object.proto | 128 +- py/client/build.gradle | 8 + .../pydeephaven/_arrow_flight_service.py | 4 +- py/client/pydeephaven/_plugin_obj_service.py | 29 + py/client/pydeephaven/_table_service.py | 11 + .../pydeephaven/experimental/__init__.py | 7 + .../pydeephaven/experimental/plugin_client.py | 131 ++ .../pydeephaven/experimental/server_object.py | 35 + py/client/pydeephaven/proto/object_pb2.py | 20 +- .../pydeephaven/proto/object_pb2_grpc.py | 152 +- py/client/pydeephaven/session.py | 27 +- py/client/pydeephaven/table.py | 5 +- py/client/tests/test_multi_session.py | 4 +- py/client/tests/test_plugin_client.py | 37 + py/server/deephaven/pandasplugin/__init__.py | 5 +- .../deephaven/pandasplugin/pandas_as_table.py | 4 +- .../server/plugin/object/__init__.py | 54 - .../plugin/__init__.py | 4 +- .../plugin/object/__init__.py | 91 ++ .../plugin/register.py | 8 +- .../script_session/__init__.py | 0 py/server/setup.py | 2 +- .../server/object/ObjectServiceGrpcImpl.java | 403 +++-- .../python/Deephaven2ServerPluginModule.java | 2 +- .../server/plugin/python/ExporterAdapter.java | 8 +- .../plugin/python/ObjectTypeAdapter.java | 70 +- .../server/session/SessionState.java | 6 +- .../server/object/ObjectServiceTest.java | 46 +- .../web/client/api/HasEventHandling.java | 8 +- .../web/client/api/JsPartitionedTable.java | 8 +- .../io/deephaven/web/client/api/JsTable.java | 57 +- .../web/client/api/JsTotalsTable.java | 12 +- .../web/client/api/ServerObject.java | 73 + .../web/client/api/WorkerConnection.java | 37 +- .../web/client/api/tree/JsTreeTable.java | 8 +- .../web/client/api/widget/JsWidget.java | 275 +++- .../api/widget/JsWidgetExportedObject.java | 25 +- .../api/widget/WidgetMessageDetails.java | 40 + .../web/client/api/widget/plot/JsFigure.java | 36 +- .../proto/object_pb/BrowserNextResponse.java | 29 + .../proto/object_pb/ConnectRequest.java | 229 +++ .../io/deephaven/proto/object_pb/Data.java | 417 ++++++ .../proto/object_pb/FetchObjectResponse.java | 88 +- .../proto/object_pb/StreamRequest.java | 419 ++++++ .../proto/object_pb/StreamResponse.java | 375 +++++ .../object_pb/streamrequest/MessageCase.java | 15 + .../object_pb/streamresponse/MessageCase.java | 15 + .../object_pb_service/ObjectService.java | 135 ++ .../ObjectServiceClient.java | 158 ++ 72 files changed, 6998 insertions(+), 547 deletions(-) create mode 100644 plugin/src/main/java/io/deephaven/plugin/type/Exporter.java create mode 100644 plugin/src/main/java/io/deephaven/plugin/type/ObjectCommunicationException.java create mode 100644 py/client/pydeephaven/_plugin_obj_service.py create mode 100644 py/client/pydeephaven/experimental/__init__.py create mode 100644 py/client/pydeephaven/experimental/plugin_client.py create mode 100644 py/client/pydeephaven/experimental/server_object.py create mode 100644 py/client/tests/test_plugin_client.py delete mode 100644 py/server/deephaven/server/plugin/object/__init__.py rename py/server/{deephaven/server => deephaven_internal}/plugin/__init__.py (73%) create mode 100644 py/server/deephaven_internal/plugin/object/__init__.py rename py/server/{deephaven/server => deephaven_internal}/plugin/register.py (75%) rename py/server/{deephaven/server => deephaven_internal}/script_session/__init__.py (100%) create mode 100644 web/client-api/src/main/java/io/deephaven/web/client/api/ServerObject.java create mode 100644 web/client-api/src/main/java/io/deephaven/web/client/api/widget/WidgetMessageDetails.java create mode 100644 web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/BrowserNextResponse.java create mode 100644 web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/ConnectRequest.java create mode 100644 web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/Data.java create mode 100644 web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamRequest.java create mode 100644 web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamResponse.java create mode 100644 web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamrequest/MessageCase.java create mode 100644 web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamresponse/MessageCase.java diff --git a/.gitignore b/.gitignore index b769e45c7cb..234a7cd7398 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,8 @@ workspaces/ devopsLocal/ pyclient/venv pyclient/dist -pyclient/*.egg-info +.venv/ +*.egg-info/ jenkins/failures diff --git a/Integrations/src/main/java/io/deephaven/integrations/python/PythonDeephavenSession.java b/Integrations/src/main/java/io/deephaven/integrations/python/PythonDeephavenSession.java index 3222f6613f7..06f7766f7df 100644 --- a/Integrations/src/main/java/io/deephaven/integrations/python/PythonDeephavenSession.java +++ b/Integrations/src/main/java/io/deephaven/integrations/python/PythonDeephavenSession.java @@ -43,7 +43,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -87,7 +86,7 @@ public PythonDeephavenSession( scope = pythonEvaluator.getScope(); executionContext.getQueryLibrary().importClass(org.jpy.PyObject.class); try (final SafeCloseable ignored = executionContext.open()) { - module = (PythonScriptSessionModule) PyModule.importModule("deephaven.server.script_session") + module = (PythonScriptSessionModule) PyModule.importModule("deephaven_internal.script_session") .createProxy(CallableKind.FUNCTION, PythonScriptSessionModule.class); } scriptFinder = new ScriptFinder(DEFAULT_SCRIPT_PATH); @@ -116,7 +115,7 @@ public PythonDeephavenSession( evaluator = null; this.scope = (PythonScope) scope; try (final SafeCloseable ignored = executionContext.open()) { - module = (PythonScriptSessionModule) PyModule.importModule("deephaven.server.script_session") + module = (PythonScriptSessionModule) PyModule.importModule("deephaven_internal.script_session") .createProxy(CallableKind.FUNCTION, PythonScriptSessionModule.class); } scriptFinder = null; diff --git a/authorization/src/main/java/io/deephaven/auth/codegen/impl/ObjectServiceAuthWiring.java b/authorization/src/main/java/io/deephaven/auth/codegen/impl/ObjectServiceAuthWiring.java index 79651563397..1feba9e8ed2 100644 --- a/authorization/src/main/java/io/deephaven/auth/codegen/impl/ObjectServiceAuthWiring.java +++ b/authorization/src/main/java/io/deephaven/auth/codegen/impl/ObjectServiceAuthWiring.java @@ -11,6 +11,7 @@ import io.deephaven.auth.ServiceAuthWiring; import io.deephaven.proto.backplane.grpc.FetchObjectRequest; import io.deephaven.proto.backplane.grpc.ObjectServiceGrpc; +import io.deephaven.proto.backplane.grpc.StreamRequest; import io.grpc.ServerServiceDefinition; /** @@ -30,6 +31,12 @@ default ServerServiceDefinition intercept(ObjectServiceGrpc.ObjectServiceImplBas serviceBuilder.addMethod(ServiceAuthWiring.intercept( service, "FetchObject", null, this::onMessageReceivedFetchObject)); + serviceBuilder.addMethod(ServiceAuthWiring.intercept( + service, "MessageStream", this::onCallStartedMessageStream, this::onMessageReceivedMessageStream)); + serviceBuilder.addMethod(ServiceAuthWiring.intercept( + service, "OpenMessageStream", null, this::onMessageReceivedOpenMessageStream)); + serviceBuilder.addMethod(ServiceAuthWiring.intercept( + service, "NextMessageStream", null, this::onMessageReceivedNextMessageStream)); return serviceBuilder.build(); } @@ -43,14 +50,77 @@ default ServerServiceDefinition intercept(ObjectServiceGrpc.ObjectServiceImplBas */ void onMessageReceivedFetchObject(AuthContext authContext, FetchObjectRequest request); + /** + * Authorize a request to open a client-streaming rpc MessageStream. + * + * @param authContext the authentication context of the request + * @throws io.grpc.StatusRuntimeException if the user is not authorized to invoke MessageStream + */ + void onCallStartedMessageStream(AuthContext authContext); + + /** + * Authorize a request to MessageStream. + * + * @param authContext the authentication context of the request + * @param request the request to authorize + * @throws io.grpc.StatusRuntimeException if the user is not authorized to invoke MessageStream + */ + void onMessageReceivedMessageStream(AuthContext authContext, StreamRequest request); + + /** + * Authorize a request to OpenMessageStream. + * + * @param authContext the authentication context of the request + * @param request the request to authorize + * @throws io.grpc.StatusRuntimeException if the user is not authorized to invoke OpenMessageStream + */ + void onMessageReceivedOpenMessageStream(AuthContext authContext, StreamRequest request); + + /** + * Authorize a request to NextMessageStream. + * + * @param authContext the authentication context of the request + * @param request the request to authorize + * @throws io.grpc.StatusRuntimeException if the user is not authorized to invoke NextMessageStream + */ + void onMessageReceivedNextMessageStream(AuthContext authContext, StreamRequest request); + class AllowAll implements ObjectServiceAuthWiring { public void onMessageReceivedFetchObject(AuthContext authContext, FetchObjectRequest request) {} + + public void onCallStartedMessageStream(AuthContext authContext) {} + + public void onMessageReceivedMessageStream(AuthContext authContext, StreamRequest request) {} + + public void onMessageReceivedOpenMessageStream(AuthContext authContext, + StreamRequest request) {} + + public void onMessageReceivedNextMessageStream(AuthContext authContext, + StreamRequest request) {} } class DenyAll implements ObjectServiceAuthWiring { public void onMessageReceivedFetchObject(AuthContext authContext, FetchObjectRequest request) { ServiceAuthWiring.operationNotAllowed(); } + + public void onCallStartedMessageStream(AuthContext authContext) { + ServiceAuthWiring.operationNotAllowed(); + } + + public void onMessageReceivedMessageStream(AuthContext authContext, StreamRequest request) { + ServiceAuthWiring.operationNotAllowed(); + } + + public void onMessageReceivedOpenMessageStream(AuthContext authContext, + StreamRequest request) { + ServiceAuthWiring.operationNotAllowed(); + } + + public void onMessageReceivedNextMessageStream(AuthContext authContext, + StreamRequest request) { + ServiceAuthWiring.operationNotAllowed(); + } } class TestUseOnly implements ObjectServiceAuthWiring { @@ -61,5 +131,31 @@ public void onMessageReceivedFetchObject(AuthContext authContext, FetchObjectReq delegate.onMessageReceivedFetchObject(authContext, request); } } + + public void onCallStartedMessageStream(AuthContext authContext) { + if (delegate != null) { + delegate.onCallStartedMessageStream(authContext); + } + } + + public void onMessageReceivedMessageStream(AuthContext authContext, StreamRequest request) { + if (delegate != null) { + delegate.onMessageReceivedMessageStream(authContext, request); + } + } + + public void onMessageReceivedOpenMessageStream(AuthContext authContext, + StreamRequest request) { + if (delegate != null) { + delegate.onMessageReceivedOpenMessageStream(authContext, request); + } + } + + public void onMessageReceivedNextMessageStream(AuthContext authContext, + StreamRequest request) { + if (delegate != null) { + delegate.onMessageReceivedNextMessageStream(authContext, request); + } + } } } diff --git a/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.cc b/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.cc index a639e4dd108..258af92cf93 100644 --- a/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.cc +++ b/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.cc @@ -27,6 +27,9 @@ namespace grpc { static const char* ObjectService_method_names[] = { "/io.deephaven.proto.backplane.grpc.ObjectService/FetchObject", + "/io.deephaven.proto.backplane.grpc.ObjectService/MessageStream", + "/io.deephaven.proto.backplane.grpc.ObjectService/OpenMessageStream", + "/io.deephaven.proto.backplane.grpc.ObjectService/NextMessageStream", }; std::unique_ptr< ObjectService::Stub> ObjectService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) { @@ -37,6 +40,9 @@ std::unique_ptr< ObjectService::Stub> ObjectService::NewStub(const std::shared_p ObjectService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) : channel_(channel), rpcmethod_FetchObject_(ObjectService_method_names[0], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_MessageStream_(ObjectService_method_names[1], options.suffix_for_stats(),::grpc::internal::RpcMethod::BIDI_STREAMING, channel) + , rpcmethod_OpenMessageStream_(ObjectService_method_names[2], options.suffix_for_stats(),::grpc::internal::RpcMethod::SERVER_STREAMING, channel) + , rpcmethod_NextMessageStream_(ObjectService_method_names[3], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) {} ::grpc::Status ObjectService::Stub::FetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* response) { @@ -62,6 +68,61 @@ ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::Fetc return result; } +::grpc::ClientReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* ObjectService::Stub::MessageStreamRaw(::grpc::ClientContext* context) { + return ::grpc::internal::ClientReaderWriterFactory< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(channel_.get(), rpcmethod_MessageStream_, context); +} + +void ObjectService::Stub::async::MessageStream(::grpc::ClientContext* context, ::grpc::ClientBidiReactor< ::io::deephaven::proto::backplane::grpc::StreamRequest,::io::deephaven::proto::backplane::grpc::StreamResponse>* reactor) { + ::grpc::internal::ClientCallbackReaderWriterFactory< ::io::deephaven::proto::backplane::grpc::StreamRequest,::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(stub_->channel_.get(), stub_->rpcmethod_MessageStream_, context, reactor); +} + +::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* ObjectService::Stub::AsyncMessageStreamRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return ::grpc::internal::ClientAsyncReaderWriterFactory< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(channel_.get(), cq, rpcmethod_MessageStream_, context, true, tag); +} + +::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* ObjectService::Stub::PrepareAsyncMessageStreamRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncReaderWriterFactory< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(channel_.get(), cq, rpcmethod_MessageStream_, context, false, nullptr); +} + +::grpc::ClientReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>* ObjectService::Stub::OpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request) { + return ::grpc::internal::ClientReaderFactory< ::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(channel_.get(), rpcmethod_OpenMessageStream_, context, request); +} + +void ObjectService::Stub::async::OpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::grpc::ClientReadReactor< ::io::deephaven::proto::backplane::grpc::StreamResponse>* reactor) { + ::grpc::internal::ClientCallbackReaderFactory< ::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(stub_->channel_.get(), stub_->rpcmethod_OpenMessageStream_, context, request, reactor); +} + +::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>* ObjectService::Stub::AsyncOpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq, void* tag) { + return ::grpc::internal::ClientAsyncReaderFactory< ::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(channel_.get(), cq, rpcmethod_OpenMessageStream_, context, request, true, tag); +} + +::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>* ObjectService::Stub::PrepareAsyncOpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncReaderFactory< ::io::deephaven::proto::backplane::grpc::StreamResponse>::Create(channel_.get(), cq, rpcmethod_OpenMessageStream_, context, request, false, nullptr); +} + +::grpc::Status ObjectService::Stub::NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response) { + return ::grpc::internal::BlockingUnaryCall< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_NextMessageStream_, context, request, response); +} + +void ObjectService::Stub::async::NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response, std::function f) { + ::grpc::internal::CallbackUnaryCall< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_NextMessageStream_, context, request, response, std::move(f)); +} + +void ObjectService::Stub::async::NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response, ::grpc::ClientUnaryReactor* reactor) { + ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_NextMessageStream_, context, request, response, reactor); +} + +::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* ObjectService::Stub::PrepareAsyncNextMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_NextMessageStream_, context, request); +} + +::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* ObjectService::Stub::AsyncNextMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + auto* result = + this->PrepareAsyncNextMessageStreamRaw(context, request, cq); + result->StartCall(); + return result; +} + ObjectService::Service::Service() { AddMethod(new ::grpc::internal::RpcServiceMethod( ObjectService_method_names[0], @@ -73,6 +134,36 @@ ObjectService::Service::Service() { ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* resp) { return service->FetchObject(ctx, req, resp); }, this))); + AddMethod(new ::grpc::internal::RpcServiceMethod( + ObjectService_method_names[1], + ::grpc::internal::RpcMethod::BIDI_STREAMING, + new ::grpc::internal::BidiStreamingHandler< ObjectService::Service, ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>( + [](ObjectService::Service* service, + ::grpc::ServerContext* ctx, + ::grpc::ServerReaderWriter<::io::deephaven::proto::backplane::grpc::StreamResponse, + ::io::deephaven::proto::backplane::grpc::StreamRequest>* stream) { + return service->MessageStream(ctx, stream); + }, this))); + AddMethod(new ::grpc::internal::RpcServiceMethod( + ObjectService_method_names[2], + ::grpc::internal::RpcMethod::SERVER_STREAMING, + new ::grpc::internal::ServerStreamingHandler< ObjectService::Service, ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>( + [](ObjectService::Service* service, + ::grpc::ServerContext* ctx, + const ::io::deephaven::proto::backplane::grpc::StreamRequest* req, + ::grpc::ServerWriter<::io::deephaven::proto::backplane::grpc::StreamResponse>* writer) { + return service->OpenMessageStream(ctx, req, writer); + }, this))); + AddMethod(new ::grpc::internal::RpcServiceMethod( + ObjectService_method_names[3], + ::grpc::internal::RpcMethod::NORMAL_RPC, + new ::grpc::internal::RpcMethodHandler< ObjectService::Service, ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( + [](ObjectService::Service* service, + ::grpc::ServerContext* ctx, + const ::io::deephaven::proto::backplane::grpc::StreamRequest* req, + ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* resp) { + return service->NextMessageStream(ctx, req, resp); + }, this))); } ObjectService::Service::~Service() { @@ -85,6 +176,26 @@ ::grpc::Status ObjectService::Service::FetchObject(::grpc::ServerContext* contex return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } +::grpc::Status ObjectService::Service::MessageStream(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* stream) { + (void) context; + (void) stream; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + +::grpc::Status ObjectService::Service::OpenMessageStream(::grpc::ServerContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* writer) { + (void) context; + (void) request; + (void) writer; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + +::grpc::Status ObjectService::Service::NextMessageStream(::grpc::ServerContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + } // namespace io } // namespace deephaven diff --git a/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.h b/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.h index 817132f2ffb..49d4a01b1d9 100644 --- a/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.h +++ b/cpp-client/deephaven/client/proto/deephaven/proto/object.grpc.pb.h @@ -42,6 +42,13 @@ class ObjectService final { class StubInterface { public: virtual ~StubInterface() {} + // + // Fetches a server-side object as a binary payload and assorted other tickets pointing at + // other server-side objects that may need to be read to properly use this payload. The binary + // format is implementation specific, but the implementation should be specified by the "type" + // identifier in the typed ticket. + // + // Deprecated in favor of MessageStream, which is able to handle the same content. virtual ::grpc::Status FetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* response) = 0; std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>> AsyncFetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>>(AsyncFetchObjectRaw(context, request, cq)); @@ -49,11 +56,135 @@ class ObjectService final { std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>> PrepareAsyncFetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>>(PrepareAsyncFetchObjectRaw(context, request, cq)); } + // + // Provides a generic stream feature for Deephaven instances to use to add arbitrary functionality. + // Presently these take the form of "object type plugins", where server-side code can specify how + // an object could be serialized and/or communicate with a client. This gRPC stream is somewhat lower level + // than the plugin API, giving the server and client APIs features to correctly establish and + // control the stream. At this time, this is limited to a "ConnectRequest" to start the call. + // + // The first message sent to the server is expected to have a ConnectRequest, indicating which + // export ticket to connect to. It is an error for the client to attempt to connect to an object + // that has no plugin for its object type installed. + // + // The first request sent by the client should be a ConnectRequest. No other client message should + // be sent until the server responds. The server will respond with Data as soon as it is able (i.e. + // once the object in question has been resolved and the plugin has responded), indicating that the + // request was successful. After that point, the client may send Data requests. + // + // All replies from the server to the client contain Data instances. When sent from the server to + // the client, Data contains a bytes payload created by the server implementation of the plugin, + // and server-created export tickets containing any object references specified to be sent by the + // server-side plugin. As server-created exports, they are already resolved, and can be fetched or + // otherwise referenced right away. The client API is expected to wrap those tickets in appropriate + // objects, and the client is expected to release those tickets as appropriate, according to the + // plugin's use case. Note that it is possible for the "type" field to be null, indicating that + // there is no corresponding ObjectType plugin for these exported objects. This limits the client + // to specifying those tickets in a subsequent request, or releasing the ticket to let the object + // be garbage collected on the server. + // + // All Data instances sent from the client likewise contain a bytes payload, and may contain + // references to objects that already exist or may soon exist on the server, not just tickets sent + // by this same plugin. Note however that if those tickets are not yet resolved, neither the current + // Data nor subsequent requests can be processed by the plugin, as the required references can't be + // resolved. + // + // Presently there is no explicit "close" message to send, but plugin implementations can devise + // their own "half-close" protocol if they so choose. For now, if one end closes the connection, + // the other is expected to follow suit by closing their end too. At present, if there is an error + // with the stream, it is conveyed to the client in the usual gRPC fashion, but the server plugin + // will only be informed that the stream closed. + // + std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>> MessageStream(::grpc::ClientContext* context) { + return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>>(MessageStreamRaw(context)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>> AsyncMessageStream(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>>(AsyncMessageStreamRaw(context, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>> PrepareAsyncMessageStream(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>>(PrepareAsyncMessageStreamRaw(context, cq)); + } + // + // Half of the browser-based (browser's can't do bidirectional streams without websockets) + // implementation for MessageStream. + std::unique_ptr< ::grpc::ClientReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>> OpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request) { + return std::unique_ptr< ::grpc::ClientReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>>(OpenMessageStreamRaw(context, request)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>> AsyncOpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>>(AsyncOpenMessageStreamRaw(context, request, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>> PrepareAsyncOpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>>(PrepareAsyncOpenMessageStreamRaw(context, request, cq)); + } + // + // Other half of the browser-based implementation for MessageStream. + virtual ::grpc::Status NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>> AsyncNextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>>(AsyncNextMessageStreamRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>> PrepareAsyncNextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>>(PrepareAsyncNextMessageStreamRaw(context, request, cq)); + } class async_interface { public: virtual ~async_interface() {} + // + // Fetches a server-side object as a binary payload and assorted other tickets pointing at + // other server-side objects that may need to be read to properly use this payload. The binary + // format is implementation specific, but the implementation should be specified by the "type" + // identifier in the typed ticket. + // + // Deprecated in favor of MessageStream, which is able to handle the same content. virtual void FetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* request, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* response, std::function) = 0; virtual void FetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* request, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0; + // + // Provides a generic stream feature for Deephaven instances to use to add arbitrary functionality. + // Presently these take the form of "object type plugins", where server-side code can specify how + // an object could be serialized and/or communicate with a client. This gRPC stream is somewhat lower level + // than the plugin API, giving the server and client APIs features to correctly establish and + // control the stream. At this time, this is limited to a "ConnectRequest" to start the call. + // + // The first message sent to the server is expected to have a ConnectRequest, indicating which + // export ticket to connect to. It is an error for the client to attempt to connect to an object + // that has no plugin for its object type installed. + // + // The first request sent by the client should be a ConnectRequest. No other client message should + // be sent until the server responds. The server will respond with Data as soon as it is able (i.e. + // once the object in question has been resolved and the plugin has responded), indicating that the + // request was successful. After that point, the client may send Data requests. + // + // All replies from the server to the client contain Data instances. When sent from the server to + // the client, Data contains a bytes payload created by the server implementation of the plugin, + // and server-created export tickets containing any object references specified to be sent by the + // server-side plugin. As server-created exports, they are already resolved, and can be fetched or + // otherwise referenced right away. The client API is expected to wrap those tickets in appropriate + // objects, and the client is expected to release those tickets as appropriate, according to the + // plugin's use case. Note that it is possible for the "type" field to be null, indicating that + // there is no corresponding ObjectType plugin for these exported objects. This limits the client + // to specifying those tickets in a subsequent request, or releasing the ticket to let the object + // be garbage collected on the server. + // + // All Data instances sent from the client likewise contain a bytes payload, and may contain + // references to objects that already exist or may soon exist on the server, not just tickets sent + // by this same plugin. Note however that if those tickets are not yet resolved, neither the current + // Data nor subsequent requests can be processed by the plugin, as the required references can't be + // resolved. + // + // Presently there is no explicit "close" message to send, but plugin implementations can devise + // their own "half-close" protocol if they so choose. For now, if one end closes the connection, + // the other is expected to follow suit by closing their end too. At present, if there is an error + // with the stream, it is conveyed to the client in the usual gRPC fashion, but the server plugin + // will only be informed that the stream closed. + // + virtual void MessageStream(::grpc::ClientContext* context, ::grpc::ClientBidiReactor< ::io::deephaven::proto::backplane::grpc::StreamRequest,::io::deephaven::proto::backplane::grpc::StreamResponse>* reactor) = 0; + // + // Half of the browser-based (browser's can't do bidirectional streams without websockets) + // implementation for MessageStream. + virtual void OpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::grpc::ClientReadReactor< ::io::deephaven::proto::backplane::grpc::StreamResponse>* reactor) = 0; + // + // Other half of the browser-based implementation for MessageStream. + virtual void NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response, std::function) = 0; + virtual void NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0; }; typedef class async_interface experimental_async_interface; virtual class async_interface* async() { return nullptr; } @@ -61,6 +192,14 @@ class ObjectService final { private: virtual ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>* AsyncFetchObjectRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>* PrepareAsyncFetchObjectRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* MessageStreamRaw(::grpc::ClientContext* context) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* AsyncMessageStreamRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* PrepareAsyncMessageStreamRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>* OpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request) = 0; + virtual ::grpc::ClientAsyncReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>* AsyncOpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderInterface< ::io::deephaven::proto::backplane::grpc::StreamResponse>* PrepareAsyncOpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* AsyncNextMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* PrepareAsyncNextMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) = 0; }; class Stub final : public StubInterface { public: @@ -72,11 +211,40 @@ class ObjectService final { std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>> PrepareAsyncFetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>>(PrepareAsyncFetchObjectRaw(context, request, cq)); } + std::unique_ptr< ::grpc::ClientReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>> MessageStream(::grpc::ClientContext* context) { + return std::unique_ptr< ::grpc::ClientReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>>(MessageStreamRaw(context)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>> AsyncMessageStream(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>>(AsyncMessageStreamRaw(context, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>> PrepareAsyncMessageStream(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>>(PrepareAsyncMessageStreamRaw(context, cq)); + } + std::unique_ptr< ::grpc::ClientReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>> OpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request) { + return std::unique_ptr< ::grpc::ClientReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>>(OpenMessageStreamRaw(context, request)); + } + std::unique_ptr< ::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>> AsyncOpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>>(AsyncOpenMessageStreamRaw(context, request, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>> PrepareAsyncOpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>>(PrepareAsyncOpenMessageStreamRaw(context, request, cq)); + } + ::grpc::Status NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>> AsyncNextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>>(AsyncNextMessageStreamRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>> PrepareAsyncNextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>>(PrepareAsyncNextMessageStreamRaw(context, request, cq)); + } class async final : public StubInterface::async_interface { public: void FetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* request, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* response, std::function) override; void FetchObject(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* request, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* response, ::grpc::ClientUnaryReactor* reactor) override; + void MessageStream(::grpc::ClientContext* context, ::grpc::ClientBidiReactor< ::io::deephaven::proto::backplane::grpc::StreamRequest,::io::deephaven::proto::backplane::grpc::StreamResponse>* reactor) override; + void OpenMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::grpc::ClientReadReactor< ::io::deephaven::proto::backplane::grpc::StreamResponse>* reactor) override; + void NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response, std::function) override; + void NextMessageStream(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response, ::grpc::ClientUnaryReactor* reactor) override; private: friend class Stub; explicit async(Stub* stub): stub_(stub) { } @@ -90,7 +258,18 @@ class ObjectService final { class async async_stub_{this}; ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>* AsyncFetchObjectRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse>* PrepareAsyncFetchObjectRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* MessageStreamRaw(::grpc::ClientContext* context) override; + ::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* AsyncMessageStreamRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* PrepareAsyncMessageStreamRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>* OpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request) override; + ::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>* AsyncOpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReader< ::io::deephaven::proto::backplane::grpc::StreamResponse>* PrepareAsyncOpenMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* AsyncNextMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* PrepareAsyncNextMessageStreamRaw(::grpc::ClientContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest& request, ::grpc::CompletionQueue* cq) override; const ::grpc::internal::RpcMethod rpcmethod_FetchObject_; + const ::grpc::internal::RpcMethod rpcmethod_MessageStream_; + const ::grpc::internal::RpcMethod rpcmethod_OpenMessageStream_; + const ::grpc::internal::RpcMethod rpcmethod_NextMessageStream_; }; static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); @@ -98,7 +277,61 @@ class ObjectService final { public: Service(); virtual ~Service(); + // + // Fetches a server-side object as a binary payload and assorted other tickets pointing at + // other server-side objects that may need to be read to properly use this payload. The binary + // format is implementation specific, but the implementation should be specified by the "type" + // identifier in the typed ticket. + // + // Deprecated in favor of MessageStream, which is able to handle the same content. virtual ::grpc::Status FetchObject(::grpc::ServerContext* context, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* request, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* response); + // + // Provides a generic stream feature for Deephaven instances to use to add arbitrary functionality. + // Presently these take the form of "object type plugins", where server-side code can specify how + // an object could be serialized and/or communicate with a client. This gRPC stream is somewhat lower level + // than the plugin API, giving the server and client APIs features to correctly establish and + // control the stream. At this time, this is limited to a "ConnectRequest" to start the call. + // + // The first message sent to the server is expected to have a ConnectRequest, indicating which + // export ticket to connect to. It is an error for the client to attempt to connect to an object + // that has no plugin for its object type installed. + // + // The first request sent by the client should be a ConnectRequest. No other client message should + // be sent until the server responds. The server will respond with Data as soon as it is able (i.e. + // once the object in question has been resolved and the plugin has responded), indicating that the + // request was successful. After that point, the client may send Data requests. + // + // All replies from the server to the client contain Data instances. When sent from the server to + // the client, Data contains a bytes payload created by the server implementation of the plugin, + // and server-created export tickets containing any object references specified to be sent by the + // server-side plugin. As server-created exports, they are already resolved, and can be fetched or + // otherwise referenced right away. The client API is expected to wrap those tickets in appropriate + // objects, and the client is expected to release those tickets as appropriate, according to the + // plugin's use case. Note that it is possible for the "type" field to be null, indicating that + // there is no corresponding ObjectType plugin for these exported objects. This limits the client + // to specifying those tickets in a subsequent request, or releasing the ticket to let the object + // be garbage collected on the server. + // + // All Data instances sent from the client likewise contain a bytes payload, and may contain + // references to objects that already exist or may soon exist on the server, not just tickets sent + // by this same plugin. Note however that if those tickets are not yet resolved, neither the current + // Data nor subsequent requests can be processed by the plugin, as the required references can't be + // resolved. + // + // Presently there is no explicit "close" message to send, but plugin implementations can devise + // their own "half-close" protocol if they so choose. For now, if one end closes the connection, + // the other is expected to follow suit by closing their end too. At present, if there is an error + // with the stream, it is conveyed to the client in the usual gRPC fashion, but the server plugin + // will only be informed that the stream closed. + // + virtual ::grpc::Status MessageStream(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* stream); + // + // Half of the browser-based (browser's can't do bidirectional streams without websockets) + // implementation for MessageStream. + virtual ::grpc::Status OpenMessageStream(::grpc::ServerContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* writer); + // + // Other half of the browser-based implementation for MessageStream. + virtual ::grpc::Status NextMessageStream(::grpc::ServerContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response); }; template class WithAsyncMethod_FetchObject : public BaseClass { @@ -120,7 +353,67 @@ class ObjectService final { ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); } }; - typedef WithAsyncMethod_FetchObject AsyncService; + template + class WithAsyncMethod_MessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithAsyncMethod_MessageStream() { + ::grpc::Service::MarkMethodAsync(1); + } + ~WithAsyncMethod_MessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status MessageStream(::grpc::ServerContext* /*context*/, ::grpc::ServerReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* /*stream*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestMessageStream(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncBidiStreaming(1, context, stream, new_call_cq, notification_cq, tag); + } + }; + template + class WithAsyncMethod_OpenMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithAsyncMethod_OpenMessageStream() { + ::grpc::Service::MarkMethodAsync(2); + } + ~WithAsyncMethod_OpenMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status OpenMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* /*writer*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestOpenMessageStream(::grpc::ServerContext* context, ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::grpc::ServerAsyncWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag); + } + }; + template + class WithAsyncMethod_NextMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithAsyncMethod_NextMessageStream() { + ::grpc::Service::MarkMethodAsync(3); + } + ~WithAsyncMethod_NextMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status NextMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestNextMessageStream(::grpc::ServerContext* context, ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::grpc::ServerAsyncResponseWriter< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag); + } + }; + typedef WithAsyncMethod_FetchObject > > > AsyncService; template class WithCallbackMethod_FetchObject : public BaseClass { private: @@ -148,7 +441,79 @@ class ObjectService final { virtual ::grpc::ServerUnaryReactor* FetchObject( ::grpc::CallbackServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* /*response*/) { return nullptr; } }; - typedef WithCallbackMethod_FetchObject CallbackService; + template + class WithCallbackMethod_MessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithCallbackMethod_MessageStream() { + ::grpc::Service::MarkMethodCallback(1, + new ::grpc::internal::CallbackBidiHandler< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>( + [this]( + ::grpc::CallbackServerContext* context) { return this->MessageStream(context); })); + } + ~WithCallbackMethod_MessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status MessageStream(::grpc::ServerContext* /*context*/, ::grpc::ServerReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* /*stream*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerBidiReactor< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* MessageStream( + ::grpc::CallbackServerContext* /*context*/) + { return nullptr; } + }; + template + class WithCallbackMethod_OpenMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithCallbackMethod_OpenMessageStream() { + ::grpc::Service::MarkMethodCallback(2, + new ::grpc::internal::CallbackServerStreamingHandler< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>( + [this]( + ::grpc::CallbackServerContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request) { return this->OpenMessageStream(context, request); })); + } + ~WithCallbackMethod_OpenMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status OpenMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* /*writer*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerWriteReactor< ::io::deephaven::proto::backplane::grpc::StreamResponse>* OpenMessageStream( + ::grpc::CallbackServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/) { return nullptr; } + }; + template + class WithCallbackMethod_NextMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithCallbackMethod_NextMessageStream() { + ::grpc::Service::MarkMethodCallback(3, + new ::grpc::internal::CallbackUnaryHandler< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>( + [this]( + ::grpc::CallbackServerContext* context, const ::io::deephaven::proto::backplane::grpc::StreamRequest* request, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* response) { return this->NextMessageStream(context, request, response); }));} + void SetMessageAllocatorFor_NextMessageStream( + ::grpc::MessageAllocator< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* allocator) { + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(3); + static_cast<::grpc::internal::CallbackUnaryHandler< ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>*>(handler) + ->SetMessageAllocator(allocator); + } + ~WithCallbackMethod_NextMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status NextMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerUnaryReactor* NextMessageStream( + ::grpc::CallbackServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* /*response*/) { return nullptr; } + }; + typedef WithCallbackMethod_FetchObject > > > CallbackService; typedef CallbackService ExperimentalCallbackService; template class WithGenericMethod_FetchObject : public BaseClass { @@ -168,6 +533,57 @@ class ObjectService final { } }; template + class WithGenericMethod_MessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithGenericMethod_MessageStream() { + ::grpc::Service::MarkMethodGeneric(1); + } + ~WithGenericMethod_MessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status MessageStream(::grpc::ServerContext* /*context*/, ::grpc::ServerReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* /*stream*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithGenericMethod_OpenMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithGenericMethod_OpenMessageStream() { + ::grpc::Service::MarkMethodGeneric(2); + } + ~WithGenericMethod_OpenMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status OpenMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* /*writer*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithGenericMethod_NextMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithGenericMethod_NextMessageStream() { + ::grpc::Service::MarkMethodGeneric(3); + } + ~WithGenericMethod_NextMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status NextMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template class WithRawMethod_FetchObject : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} @@ -188,6 +604,66 @@ class ObjectService final { } }; template + class WithRawMethod_MessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawMethod_MessageStream() { + ::grpc::Service::MarkMethodRaw(1); + } + ~WithRawMethod_MessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status MessageStream(::grpc::ServerContext* /*context*/, ::grpc::ServerReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* /*stream*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestMessageStream(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncBidiStreaming(1, context, stream, new_call_cq, notification_cq, tag); + } + }; + template + class WithRawMethod_OpenMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawMethod_OpenMessageStream() { + ::grpc::Service::MarkMethodRaw(2); + } + ~WithRawMethod_OpenMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status OpenMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* /*writer*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestOpenMessageStream(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncServerStreaming(2, context, request, writer, new_call_cq, notification_cq, tag); + } + }; + template + class WithRawMethod_NextMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawMethod_NextMessageStream() { + ::grpc::Service::MarkMethodRaw(3); + } + ~WithRawMethod_NextMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status NextMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestNextMessageStream(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template class WithRawCallbackMethod_FetchObject : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} @@ -210,6 +686,73 @@ class ObjectService final { ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; } }; template + class WithRawCallbackMethod_MessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawCallbackMethod_MessageStream() { + ::grpc::Service::MarkMethodRawCallback(1, + new ::grpc::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this]( + ::grpc::CallbackServerContext* context) { return this->MessageStream(context); })); + } + ~WithRawCallbackMethod_MessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status MessageStream(::grpc::ServerContext* /*context*/, ::grpc::ServerReaderWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse, ::io::deephaven::proto::backplane::grpc::StreamRequest>* /*stream*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MessageStream( + ::grpc::CallbackServerContext* /*context*/) + { return nullptr; } + }; + template + class WithRawCallbackMethod_OpenMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawCallbackMethod_OpenMessageStream() { + ::grpc::Service::MarkMethodRawCallback(2, + new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this]( + ::grpc::CallbackServerContext* context, const::grpc::ByteBuffer* request) { return this->OpenMessageStream(context, request); })); + } + ~WithRawCallbackMethod_OpenMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status OpenMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* /*writer*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerWriteReactor< ::grpc::ByteBuffer>* OpenMessageStream( + ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/) { return nullptr; } + }; + template + class WithRawCallbackMethod_NextMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawCallbackMethod_NextMessageStream() { + ::grpc::Service::MarkMethodRawCallback(3, + new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this]( + ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->NextMessageStream(context, request, response); })); + } + ~WithRawCallbackMethod_NextMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status NextMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerUnaryReactor* NextMessageStream( + ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; } + }; + template class WithStreamedUnaryMethod_FetchObject : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} @@ -236,9 +779,63 @@ class ObjectService final { // replace default version of method with streamed unary virtual ::grpc::Status StreamedFetchObject(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::io::deephaven::proto::backplane::grpc::FetchObjectRequest,::io::deephaven::proto::backplane::grpc::FetchObjectResponse>* server_unary_streamer) = 0; }; - typedef WithStreamedUnaryMethod_FetchObject StreamedUnaryService; - typedef Service SplitStreamedService; - typedef WithStreamedUnaryMethod_FetchObject StreamedService; + template + class WithStreamedUnaryMethod_NextMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithStreamedUnaryMethod_NextMessageStream() { + ::grpc::Service::MarkMethodStreamed(3, + new ::grpc::internal::StreamedUnaryHandler< + ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>( + [this](::grpc::ServerContext* context, + ::grpc::ServerUnaryStreamer< + ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* streamer) { + return this->StreamedNextMessageStream(context, + streamer); + })); + } + ~WithStreamedUnaryMethod_NextMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status NextMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedNextMessageStream(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::io::deephaven::proto::backplane::grpc::StreamRequest,::io::deephaven::proto::backplane::grpc::BrowserNextResponse>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_FetchObject > StreamedUnaryService; + template + class WithSplitStreamingMethod_OpenMessageStream : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithSplitStreamingMethod_OpenMessageStream() { + ::grpc::Service::MarkMethodStreamed(2, + new ::grpc::internal::SplitServerStreamingHandler< + ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>( + [this](::grpc::ServerContext* context, + ::grpc::ServerSplitStreamer< + ::io::deephaven::proto::backplane::grpc::StreamRequest, ::io::deephaven::proto::backplane::grpc::StreamResponse>* streamer) { + return this->StreamedOpenMessageStream(context, + streamer); + })); + } + ~WithSplitStreamingMethod_OpenMessageStream() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status OpenMessageStream(::grpc::ServerContext* /*context*/, const ::io::deephaven::proto::backplane::grpc::StreamRequest* /*request*/, ::grpc::ServerWriter< ::io::deephaven::proto::backplane::grpc::StreamResponse>* /*writer*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with split streamed + virtual ::grpc::Status StreamedOpenMessageStream(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::io::deephaven::proto::backplane::grpc::StreamRequest,::io::deephaven::proto::backplane::grpc::StreamResponse>* server_split_streamer) = 0; + }; + typedef WithSplitStreamingMethod_OpenMessageStream SplitStreamedService; + typedef WithStreamedUnaryMethod_FetchObject > > StreamedService; }; } // namespace grpc diff --git a/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.cc b/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.cc index b50560a16e1..5f9cfe8e6bd 100644 --- a/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.cc +++ b/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.cc @@ -39,7 +39,7 @@ struct FetchObjectRequestDefaultTypeInternal { PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FetchObjectRequestDefaultTypeInternal _FetchObjectRequest_default_instance_; PROTOBUF_CONSTEXPR FetchObjectResponse::FetchObjectResponse( ::_pbi::ConstantInitialized) - : typed_export_id_() + : typed_export_ids_() , type_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , data_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}){} struct FetchObjectResponseDefaultTypeInternal { @@ -51,12 +51,72 @@ struct FetchObjectResponseDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FetchObjectResponseDefaultTypeInternal _FetchObjectResponse_default_instance_; +PROTOBUF_CONSTEXPR ConnectRequest::ConnectRequest( + ::_pbi::ConstantInitialized) + : source_id_(nullptr){} +struct ConnectRequestDefaultTypeInternal { + PROTOBUF_CONSTEXPR ConnectRequestDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~ConnectRequestDefaultTypeInternal() {} + union { + ConnectRequest _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ConnectRequestDefaultTypeInternal _ConnectRequest_default_instance_; +PROTOBUF_CONSTEXPR Data::Data( + ::_pbi::ConstantInitialized) + : exported_references_() + , payload_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}){} +struct DataDefaultTypeInternal { + PROTOBUF_CONSTEXPR DataDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~DataDefaultTypeInternal() {} + union { + Data _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DataDefaultTypeInternal _Data_default_instance_; +PROTOBUF_CONSTEXPR StreamRequest::StreamRequest( + ::_pbi::ConstantInitialized) + : _oneof_case_{}{} +struct StreamRequestDefaultTypeInternal { + PROTOBUF_CONSTEXPR StreamRequestDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~StreamRequestDefaultTypeInternal() {} + union { + StreamRequest _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 StreamRequestDefaultTypeInternal _StreamRequest_default_instance_; +PROTOBUF_CONSTEXPR StreamResponse::StreamResponse( + ::_pbi::ConstantInitialized) + : _oneof_case_{}{} +struct StreamResponseDefaultTypeInternal { + PROTOBUF_CONSTEXPR StreamResponseDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~StreamResponseDefaultTypeInternal() {} + union { + StreamResponse _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 StreamResponseDefaultTypeInternal _StreamResponse_default_instance_; +PROTOBUF_CONSTEXPR BrowserNextResponse::BrowserNextResponse( + ::_pbi::ConstantInitialized){} +struct BrowserNextResponseDefaultTypeInternal { + PROTOBUF_CONSTEXPR BrowserNextResponseDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~BrowserNextResponseDefaultTypeInternal() {} + union { + BrowserNextResponse _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 BrowserNextResponseDefaultTypeInternal _BrowserNextResponse_default_instance_; } // namespace grpc } // namespace backplane } // namespace proto } // namespace deephaven } // namespace io -static ::_pb::Metadata file_level_metadata_deephaven_2fproto_2fobject_2eproto[2]; +static ::_pb::Metadata file_level_metadata_deephaven_2fproto_2fobject_2eproto[7]; static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_deephaven_2fproto_2fobject_2eproto = nullptr; static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_deephaven_2fproto_2fobject_2eproto = nullptr; @@ -76,16 +136,64 @@ const uint32_t TableStruct_deephaven_2fproto_2fobject_2eproto::offsets[] PROTOBU ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::FetchObjectResponse, type_), PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::FetchObjectResponse, data_), - PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::FetchObjectResponse, typed_export_id_), + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::FetchObjectResponse, typed_export_ids_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::ConnectRequest, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::ConnectRequest, source_id_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::Data, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::Data, payload_), + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::Data, exported_references_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::StreamRequest, _internal_metadata_), + ~0u, // no _extensions_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::StreamRequest, _oneof_case_[0]), + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ::_pbi::kInvalidFieldOffsetTag, + ::_pbi::kInvalidFieldOffsetTag, + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::StreamRequest, message_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::StreamResponse, _internal_metadata_), + ~0u, // no _extensions_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::StreamResponse, _oneof_case_[0]), + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + ::_pbi::kInvalidFieldOffsetTag, + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::StreamResponse, message_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::io::deephaven::proto::backplane::grpc::BrowserNextResponse, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ }; static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, -1, sizeof(::io::deephaven::proto::backplane::grpc::FetchObjectRequest)}, { 7, -1, -1, sizeof(::io::deephaven::proto::backplane::grpc::FetchObjectResponse)}, + { 16, -1, -1, sizeof(::io::deephaven::proto::backplane::grpc::ConnectRequest)}, + { 23, -1, -1, sizeof(::io::deephaven::proto::backplane::grpc::Data)}, + { 31, -1, -1, sizeof(::io::deephaven::proto::backplane::grpc::StreamRequest)}, + { 40, -1, -1, sizeof(::io::deephaven::proto::backplane::grpc::StreamResponse)}, + { 48, -1, -1, sizeof(::io::deephaven::proto::backplane::grpc::BrowserNextResponse)}, }; static const ::_pb::Message* const file_default_instances[] = { &::io::deephaven::proto::backplane::grpc::_FetchObjectRequest_default_instance_._instance, &::io::deephaven::proto::backplane::grpc::_FetchObjectResponse_default_instance_._instance, + &::io::deephaven::proto::backplane::grpc::_ConnectRequest_default_instance_._instance, + &::io::deephaven::proto::backplane::grpc::_Data_default_instance_._instance, + &::io::deephaven::proto::backplane::grpc::_StreamRequest_default_instance_._instance, + &::io::deephaven::proto::backplane::grpc::_StreamResponse_default_instance_._instance, + &::io::deephaven::proto::backplane::grpc::_BrowserNextResponse_default_instance_._instance, }; const char descriptor_table_protodef_deephaven_2fproto_2fobject_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -93,25 +201,46 @@ const char descriptor_table_protodef_deephaven_2fproto_2fobject_2eproto[] PROTOB "aven.proto.backplane.grpc\032\034deephaven/pro" "to/ticket.proto\"W\n\022FetchObjectRequest\022A\n" "\tsource_id\030\001 \001(\0132..io.deephaven.proto.ba" - "ckplane.grpc.TypedTicket\"z\n\023FetchObjectR" - "esponse\022\014\n\004type\030\001 \001(\t\022\014\n\004data\030\002 \001(\014\022G\n\017t" - "yped_export_id\030\003 \003(\0132..io.deephaven.prot" - "o.backplane.grpc.TypedTicket2\217\001\n\rObjectS" - "ervice\022~\n\013FetchObject\0225.io.deephaven.pro" - "to.backplane.grpc.FetchObjectRequest\0326.i" - "o.deephaven.proto.backplane.grpc.FetchOb" - "jectResponse\"\000BBH\001P\001Z(from._internal_metadata_); type_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING @@ -396,7 +525,7 @@ void FetchObjectResponse::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - typed_export_id_.Clear(); + typed_export_ids_.Clear(); type_.ClearToEmpty(); data_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); @@ -427,13 +556,13 @@ const char* FetchObjectResponse::_InternalParse(const char* ptr, ::_pbi::ParseCo } else goto handle_unusual; continue; - // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_id = 3; + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_ids = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 26)) { ptr -= 1; do { ptr += 1; - ptr = ctx->ParseMessage(_internal_add_typed_export_id(), ptr); + ptr = ctx->ParseMessage(_internal_add_typed_export_ids(), ptr); CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr)); @@ -485,10 +614,10 @@ uint8_t* FetchObjectResponse::_InternalSerialize( 2, this->_internal_data(), target); } - // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_id = 3; + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_ids = 3; for (unsigned i = 0, - n = static_cast(this->_internal_typed_export_id_size()); i < n; i++) { - const auto& repfield = this->_internal_typed_export_id(i); + n = static_cast(this->_internal_typed_export_ids_size()); i < n; i++) { + const auto& repfield = this->_internal_typed_export_ids(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: InternalWriteMessage(3, repfield, repfield.GetCachedSize(), target, stream); } @@ -509,9 +638,9 @@ size_t FetchObjectResponse::ByteSizeLong() const { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_id = 3; - total_size += 1UL * this->_internal_typed_export_id_size(); - for (const auto& msg : this->typed_export_id_) { + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_ids = 3; + total_size += 1UL * this->_internal_typed_export_ids_size(); + for (const auto& msg : this->typed_export_ids_) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } @@ -552,7 +681,7 @@ void FetchObjectResponse::MergeFrom(const FetchObjectResponse& from) { uint32_t cached_has_bits = 0; (void) cached_has_bits; - typed_export_id_.MergeFrom(from.typed_export_id_); + typed_export_ids_.MergeFrom(from.typed_export_ids_); if (!from._internal_type().empty()) { _internal_set_type(from._internal_type()); } @@ -578,7 +707,7 @@ void FetchObjectResponse::InternalSwap(FetchObjectResponse* other) { auto* lhs_arena = GetArenaForAllocation(); auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - typed_export_id_.InternalSwap(&other->typed_export_id_); + typed_export_ids_.InternalSwap(&other->typed_export_ids_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( &type_, lhs_arena, &other->type_, rhs_arena @@ -595,20 +724,1024 @@ ::PROTOBUF_NAMESPACE_ID::Metadata FetchObjectResponse::GetMetadata() const { file_level_metadata_deephaven_2fproto_2fobject_2eproto[1]); } -// @@protoc_insertion_point(namespace_scope) -} // namespace grpc -} // namespace backplane -} // namespace proto -} // namespace deephaven -} // namespace io -PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* -Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::FetchObjectRequest >(Arena* arena) { - return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::FetchObjectRequest >(arena); +// =================================================================== + +class ConnectRequest::_Internal { + public: + static const ::io::deephaven::proto::backplane::grpc::TypedTicket& source_id(const ConnectRequest* msg); +}; + +const ::io::deephaven::proto::backplane::grpc::TypedTicket& +ConnectRequest::_Internal::source_id(const ConnectRequest* msg) { + return *msg->source_id_; } -template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* -Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse >(Arena* arena) { - return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse >(arena); +void ConnectRequest::clear_source_id() { + if (GetArenaForAllocation() == nullptr && source_id_ != nullptr) { + delete source_id_; + } + source_id_ = nullptr; +} +ConnectRequest::ConnectRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + // @@protoc_insertion_point(arena_constructor:io.deephaven.proto.backplane.grpc.ConnectRequest) +} +ConnectRequest::ConnectRequest(const ConnectRequest& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + if (from._internal_has_source_id()) { + source_id_ = new ::io::deephaven::proto::backplane::grpc::TypedTicket(*from.source_id_); + } else { + source_id_ = nullptr; + } + // @@protoc_insertion_point(copy_constructor:io.deephaven.proto.backplane.grpc.ConnectRequest) +} + +inline void ConnectRequest::SharedCtor() { +source_id_ = nullptr; +} + +ConnectRequest::~ConnectRequest() { + // @@protoc_insertion_point(destructor:io.deephaven.proto.backplane.grpc.ConnectRequest) + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void ConnectRequest::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + if (this != internal_default_instance()) delete source_id_; +} + +void ConnectRequest::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void ConnectRequest::Clear() { +// @@protoc_insertion_point(message_clear_start:io.deephaven.proto.backplane.grpc.ConnectRequest) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + if (GetArenaForAllocation() == nullptr && source_id_ != nullptr) { + delete source_id_; + } + source_id_ = nullptr; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* ConnectRequest::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // .io.deephaven.proto.backplane.grpc.TypedTicket source_id = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { + ptr = ctx->ParseMessage(_internal_mutable_source_id(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* ConnectRequest::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:io.deephaven.proto.backplane.grpc.ConnectRequest) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // .io.deephaven.proto.backplane.grpc.TypedTicket source_id = 1; + if (this->_internal_has_source_id()) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(1, _Internal::source_id(this), + _Internal::source_id(this).GetCachedSize(), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:io.deephaven.proto.backplane.grpc.ConnectRequest) + return target; +} + +size_t ConnectRequest::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:io.deephaven.proto.backplane.grpc.ConnectRequest) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // .io.deephaven.proto.backplane.grpc.TypedTicket source_id = 1; + if (this->_internal_has_source_id()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *source_id_); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ConnectRequest::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ConnectRequest::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ConnectRequest::GetClassData() const { return &_class_data_; } + +void ConnectRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast(to)->MergeFrom( + static_cast(from)); +} + + +void ConnectRequest::MergeFrom(const ConnectRequest& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:io.deephaven.proto.backplane.grpc.ConnectRequest) + GOOGLE_DCHECK_NE(&from, this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + if (from._internal_has_source_id()) { + _internal_mutable_source_id()->::io::deephaven::proto::backplane::grpc::TypedTicket::MergeFrom(from._internal_source_id()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void ConnectRequest::CopyFrom(const ConnectRequest& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:io.deephaven.proto.backplane.grpc.ConnectRequest) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ConnectRequest::IsInitialized() const { + return true; +} + +void ConnectRequest::InternalSwap(ConnectRequest* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(source_id_, other->source_id_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata ConnectRequest::GetMetadata() const { + return ::_pbi::AssignDescriptors( + &descriptor_table_deephaven_2fproto_2fobject_2eproto_getter, &descriptor_table_deephaven_2fproto_2fobject_2eproto_once, + file_level_metadata_deephaven_2fproto_2fobject_2eproto[2]); +} + +// =================================================================== + +class Data::_Internal { + public: +}; + +void Data::clear_exported_references() { + exported_references_.Clear(); +} +Data::Data(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), + exported_references_(arena) { + SharedCtor(); + // @@protoc_insertion_point(arena_constructor:io.deephaven.proto.backplane.grpc.Data) +} +Data::Data(const Data& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + exported_references_(from.exported_references_) { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + payload_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + payload_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_payload().empty()) { + payload_.Set(from._internal_payload(), + GetArenaForAllocation()); + } + // @@protoc_insertion_point(copy_constructor:io.deephaven.proto.backplane.grpc.Data) +} + +inline void Data::SharedCtor() { +payload_.InitDefault(); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + payload_.Set("", GetArenaForAllocation()); +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +Data::~Data() { + // @@protoc_insertion_point(destructor:io.deephaven.proto.backplane.grpc.Data) + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void Data::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + payload_.Destroy(); +} + +void Data::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void Data::Clear() { +// @@protoc_insertion_point(message_clear_start:io.deephaven.proto.backplane.grpc.Data) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + exported_references_.Clear(); + payload_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* Data::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // bytes payload = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { + auto str = _internal_mutable_payload(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket exported_references = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_exported_references(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* Data::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:io.deephaven.proto.backplane.grpc.Data) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // bytes payload = 1; + if (!this->_internal_payload().empty()) { + target = stream->WriteBytesMaybeAliased( + 1, this->_internal_payload(), target); + } + + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket exported_references = 2; + for (unsigned i = 0, + n = static_cast(this->_internal_exported_references_size()); i < n; i++) { + const auto& repfield = this->_internal_exported_references(i); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:io.deephaven.proto.backplane.grpc.Data) + return target; +} + +size_t Data::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:io.deephaven.proto.backplane.grpc.Data) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket exported_references = 2; + total_size += 1UL * this->_internal_exported_references_size(); + for (const auto& msg : this->exported_references_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // bytes payload = 1; + if (!this->_internal_payload().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( + this->_internal_payload()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Data::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + Data::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Data::GetClassData() const { return &_class_data_; } + +void Data::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast(to)->MergeFrom( + static_cast(from)); +} + + +void Data::MergeFrom(const Data& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:io.deephaven.proto.backplane.grpc.Data) + GOOGLE_DCHECK_NE(&from, this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + exported_references_.MergeFrom(from.exported_references_); + if (!from._internal_payload().empty()) { + _internal_set_payload(from._internal_payload()); + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void Data::CopyFrom(const Data& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:io.deephaven.proto.backplane.grpc.Data) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Data::IsInitialized() const { + return true; +} + +void Data::InternalSwap(Data* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + exported_references_.InternalSwap(&other->exported_references_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &payload_, lhs_arena, + &other->payload_, rhs_arena + ); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Data::GetMetadata() const { + return ::_pbi::AssignDescriptors( + &descriptor_table_deephaven_2fproto_2fobject_2eproto_getter, &descriptor_table_deephaven_2fproto_2fobject_2eproto_once, + file_level_metadata_deephaven_2fproto_2fobject_2eproto[3]); +} + +// =================================================================== + +class StreamRequest::_Internal { + public: + static const ::io::deephaven::proto::backplane::grpc::ConnectRequest& connect(const StreamRequest* msg); + static const ::io::deephaven::proto::backplane::grpc::Data& data(const StreamRequest* msg); +}; + +const ::io::deephaven::proto::backplane::grpc::ConnectRequest& +StreamRequest::_Internal::connect(const StreamRequest* msg) { + return *msg->message_.connect_; +} +const ::io::deephaven::proto::backplane::grpc::Data& +StreamRequest::_Internal::data(const StreamRequest* msg) { + return *msg->message_.data_; +} +void StreamRequest::set_allocated_connect(::io::deephaven::proto::backplane::grpc::ConnectRequest* connect) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + clear_message(); + if (connect) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(connect); + if (message_arena != submessage_arena) { + connect = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, connect, submessage_arena); + } + set_has_connect(); + message_.connect_ = connect; + } + // @@protoc_insertion_point(field_set_allocated:io.deephaven.proto.backplane.grpc.StreamRequest.connect) +} +void StreamRequest::set_allocated_data(::io::deephaven::proto::backplane::grpc::Data* data) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + clear_message(); + if (data) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(data); + if (message_arena != submessage_arena) { + data = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, data, submessage_arena); + } + set_has_data(); + message_.data_ = data; + } + // @@protoc_insertion_point(field_set_allocated:io.deephaven.proto.backplane.grpc.StreamRequest.data) +} +StreamRequest::StreamRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + // @@protoc_insertion_point(arena_constructor:io.deephaven.proto.backplane.grpc.StreamRequest) +} +StreamRequest::StreamRequest(const StreamRequest& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + clear_has_message(); + switch (from.message_case()) { + case kConnect: { + _internal_mutable_connect()->::io::deephaven::proto::backplane::grpc::ConnectRequest::MergeFrom(from._internal_connect()); + break; + } + case kData: { + _internal_mutable_data()->::io::deephaven::proto::backplane::grpc::Data::MergeFrom(from._internal_data()); + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + // @@protoc_insertion_point(copy_constructor:io.deephaven.proto.backplane.grpc.StreamRequest) +} + +inline void StreamRequest::SharedCtor() { +clear_has_message(); +} + +StreamRequest::~StreamRequest() { + // @@protoc_insertion_point(destructor:io.deephaven.proto.backplane.grpc.StreamRequest) + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void StreamRequest::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + if (has_message()) { + clear_message(); + } +} + +void StreamRequest::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void StreamRequest::clear_message() { +// @@protoc_insertion_point(one_of_clear_start:io.deephaven.proto.backplane.grpc.StreamRequest) + switch (message_case()) { + case kConnect: { + if (GetArenaForAllocation() == nullptr) { + delete message_.connect_; + } + break; + } + case kData: { + if (GetArenaForAllocation() == nullptr) { + delete message_.data_; + } + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + _oneof_case_[0] = MESSAGE_NOT_SET; +} + + +void StreamRequest::Clear() { +// @@protoc_insertion_point(message_clear_start:io.deephaven.proto.backplane.grpc.StreamRequest) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + clear_message(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* StreamRequest::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // .io.deephaven.proto.backplane.grpc.ConnectRequest connect = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { + ptr = ctx->ParseMessage(_internal_mutable_connect(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // .io.deephaven.proto.backplane.grpc.Data data = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { + ptr = ctx->ParseMessage(_internal_mutable_data(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* StreamRequest::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:io.deephaven.proto.backplane.grpc.StreamRequest) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // .io.deephaven.proto.backplane.grpc.ConnectRequest connect = 1; + if (_internal_has_connect()) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(1, _Internal::connect(this), + _Internal::connect(this).GetCachedSize(), target, stream); + } + + // .io.deephaven.proto.backplane.grpc.Data data = 2; + if (_internal_has_data()) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, _Internal::data(this), + _Internal::data(this).GetCachedSize(), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:io.deephaven.proto.backplane.grpc.StreamRequest) + return target; +} + +size_t StreamRequest::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:io.deephaven.proto.backplane.grpc.StreamRequest) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + switch (message_case()) { + // .io.deephaven.proto.backplane.grpc.ConnectRequest connect = 1; + case kConnect: { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *message_.connect_); + break; + } + // .io.deephaven.proto.backplane.grpc.Data data = 2; + case kData: { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *message_.data_); + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData StreamRequest::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + StreamRequest::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*StreamRequest::GetClassData() const { return &_class_data_; } + +void StreamRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast(to)->MergeFrom( + static_cast(from)); +} + + +void StreamRequest::MergeFrom(const StreamRequest& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:io.deephaven.proto.backplane.grpc.StreamRequest) + GOOGLE_DCHECK_NE(&from, this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + switch (from.message_case()) { + case kConnect: { + _internal_mutable_connect()->::io::deephaven::proto::backplane::grpc::ConnectRequest::MergeFrom(from._internal_connect()); + break; + } + case kData: { + _internal_mutable_data()->::io::deephaven::proto::backplane::grpc::Data::MergeFrom(from._internal_data()); + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void StreamRequest::CopyFrom(const StreamRequest& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:io.deephaven.proto.backplane.grpc.StreamRequest) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StreamRequest::IsInitialized() const { + return true; +} + +void StreamRequest::InternalSwap(StreamRequest* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(message_, other->message_); + swap(_oneof_case_[0], other->_oneof_case_[0]); +} + +::PROTOBUF_NAMESPACE_ID::Metadata StreamRequest::GetMetadata() const { + return ::_pbi::AssignDescriptors( + &descriptor_table_deephaven_2fproto_2fobject_2eproto_getter, &descriptor_table_deephaven_2fproto_2fobject_2eproto_once, + file_level_metadata_deephaven_2fproto_2fobject_2eproto[4]); +} + +// =================================================================== + +class StreamResponse::_Internal { + public: + static const ::io::deephaven::proto::backplane::grpc::Data& data(const StreamResponse* msg); +}; + +const ::io::deephaven::proto::backplane::grpc::Data& +StreamResponse::_Internal::data(const StreamResponse* msg) { + return *msg->message_.data_; +} +void StreamResponse::set_allocated_data(::io::deephaven::proto::backplane::grpc::Data* data) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + clear_message(); + if (data) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(data); + if (message_arena != submessage_arena) { + data = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, data, submessage_arena); + } + set_has_data(); + message_.data_ = data; + } + // @@protoc_insertion_point(field_set_allocated:io.deephaven.proto.backplane.grpc.StreamResponse.data) +} +StreamResponse::StreamResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(); + // @@protoc_insertion_point(arena_constructor:io.deephaven.proto.backplane.grpc.StreamResponse) +} +StreamResponse::StreamResponse(const StreamResponse& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + clear_has_message(); + switch (from.message_case()) { + case kData: { + _internal_mutable_data()->::io::deephaven::proto::backplane::grpc::Data::MergeFrom(from._internal_data()); + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + // @@protoc_insertion_point(copy_constructor:io.deephaven.proto.backplane.grpc.StreamResponse) +} + +inline void StreamResponse::SharedCtor() { +clear_has_message(); +} + +StreamResponse::~StreamResponse() { + // @@protoc_insertion_point(destructor:io.deephaven.proto.backplane.grpc.StreamResponse) + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void StreamResponse::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + if (has_message()) { + clear_message(); + } +} + +void StreamResponse::SetCachedSize(int size) const { + _cached_size_.Set(size); +} + +void StreamResponse::clear_message() { +// @@protoc_insertion_point(one_of_clear_start:io.deephaven.proto.backplane.grpc.StreamResponse) + switch (message_case()) { + case kData: { + if (GetArenaForAllocation() == nullptr) { + delete message_.data_; + } + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + _oneof_case_[0] = MESSAGE_NOT_SET; +} + + +void StreamResponse::Clear() { +// @@protoc_insertion_point(message_clear_start:io.deephaven.proto.backplane.grpc.StreamResponse) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + clear_message(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* StreamResponse::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // .io.deephaven.proto.backplane.grpc.Data data = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { + ptr = ctx->ParseMessage(_internal_mutable_data(), ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* StreamResponse::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:io.deephaven.proto.backplane.grpc.StreamResponse) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // .io.deephaven.proto.backplane.grpc.Data data = 1; + if (_internal_has_data()) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(1, _Internal::data(this), + _Internal::data(this).GetCachedSize(), target, stream); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:io.deephaven.proto.backplane.grpc.StreamResponse) + return target; +} + +size_t StreamResponse::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:io.deephaven.proto.backplane.grpc.StreamResponse) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + switch (message_case()) { + // .io.deephaven.proto.backplane.grpc.Data data = 1; + case kData: { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *message_.data_); + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData StreamResponse::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + StreamResponse::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*StreamResponse::GetClassData() const { return &_class_data_; } + +void StreamResponse::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, + const ::PROTOBUF_NAMESPACE_ID::Message& from) { + static_cast(to)->MergeFrom( + static_cast(from)); +} + + +void StreamResponse::MergeFrom(const StreamResponse& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:io.deephaven.proto.backplane.grpc.StreamResponse) + GOOGLE_DCHECK_NE(&from, this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + switch (from.message_case()) { + case kData: { + _internal_mutable_data()->::io::deephaven::proto::backplane::grpc::Data::MergeFrom(from._internal_data()); + break; + } + case MESSAGE_NOT_SET: { + break; + } + } + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void StreamResponse::CopyFrom(const StreamResponse& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:io.deephaven.proto.backplane.grpc.StreamResponse) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StreamResponse::IsInitialized() const { + return true; +} + +void StreamResponse::InternalSwap(StreamResponse* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(message_, other->message_); + swap(_oneof_case_[0], other->_oneof_case_[0]); +} + +::PROTOBUF_NAMESPACE_ID::Metadata StreamResponse::GetMetadata() const { + return ::_pbi::AssignDescriptors( + &descriptor_table_deephaven_2fproto_2fobject_2eproto_getter, &descriptor_table_deephaven_2fproto_2fobject_2eproto_once, + file_level_metadata_deephaven_2fproto_2fobject_2eproto[5]); +} + +// =================================================================== + +class BrowserNextResponse::_Internal { + public: +}; + +BrowserNextResponse::BrowserNextResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase(arena, is_message_owned) { + // @@protoc_insertion_point(arena_constructor:io.deephaven.proto.backplane.grpc.BrowserNextResponse) +} +BrowserNextResponse::BrowserNextResponse(const BrowserNextResponse& from) + : ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:io.deephaven.proto.backplane.grpc.BrowserNextResponse) +} + + + + + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData BrowserNextResponse::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl, + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl, +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*BrowserNextResponse::GetClassData() const { return &_class_data_; } + + + + + + + +::PROTOBUF_NAMESPACE_ID::Metadata BrowserNextResponse::GetMetadata() const { + return ::_pbi::AssignDescriptors( + &descriptor_table_deephaven_2fproto_2fobject_2eproto_getter, &descriptor_table_deephaven_2fproto_2fobject_2eproto_once, + file_level_metadata_deephaven_2fproto_2fobject_2eproto[6]); +} + +// @@protoc_insertion_point(namespace_scope) +} // namespace grpc +} // namespace backplane +} // namespace proto +} // namespace deephaven +} // namespace io +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* +Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::FetchObjectRequest >(Arena* arena) { + return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::FetchObjectRequest >(arena); +} +template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* +Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse >(Arena* arena) { + return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::FetchObjectResponse >(arena); +} +template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::ConnectRequest* +Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::ConnectRequest >(Arena* arena) { + return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::ConnectRequest >(arena); +} +template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::Data* +Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::Data >(Arena* arena) { + return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::Data >(arena); +} +template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::StreamRequest* +Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::StreamRequest >(Arena* arena) { + return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::StreamRequest >(arena); +} +template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::StreamResponse* +Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::StreamResponse >(Arena* arena) { + return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::StreamResponse >(arena); +} +template<> PROTOBUF_NOINLINE ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* +Arena::CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse >(Arena* arena) { + return Arena::CreateMessageInternal< ::io::deephaven::proto::backplane::grpc::BrowserNextResponse >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.h b/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.h index fe615e87e12..ecb90ed1b9d 100644 --- a/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.h +++ b/cpp-client/deephaven/client/proto/deephaven/proto/object.pb.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -50,20 +51,40 @@ namespace deephaven { namespace proto { namespace backplane { namespace grpc { +class BrowserNextResponse; +struct BrowserNextResponseDefaultTypeInternal; +extern BrowserNextResponseDefaultTypeInternal _BrowserNextResponse_default_instance_; +class ConnectRequest; +struct ConnectRequestDefaultTypeInternal; +extern ConnectRequestDefaultTypeInternal _ConnectRequest_default_instance_; +class Data; +struct DataDefaultTypeInternal; +extern DataDefaultTypeInternal _Data_default_instance_; class FetchObjectRequest; struct FetchObjectRequestDefaultTypeInternal; extern FetchObjectRequestDefaultTypeInternal _FetchObjectRequest_default_instance_; class FetchObjectResponse; struct FetchObjectResponseDefaultTypeInternal; extern FetchObjectResponseDefaultTypeInternal _FetchObjectResponse_default_instance_; +class StreamRequest; +struct StreamRequestDefaultTypeInternal; +extern StreamRequestDefaultTypeInternal _StreamRequest_default_instance_; +class StreamResponse; +struct StreamResponseDefaultTypeInternal; +extern StreamResponseDefaultTypeInternal _StreamResponse_default_instance_; } // namespace grpc } // namespace backplane } // namespace proto } // namespace deephaven } // namespace io PROTOBUF_NAMESPACE_OPEN +template<> ::io::deephaven::proto::backplane::grpc::BrowserNextResponse* Arena::CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::BrowserNextResponse>(Arena*); +template<> ::io::deephaven::proto::backplane::grpc::ConnectRequest* Arena::CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::ConnectRequest>(Arena*); +template<> ::io::deephaven::proto::backplane::grpc::Data* Arena::CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::Data>(Arena*); template<> ::io::deephaven::proto::backplane::grpc::FetchObjectRequest* Arena::CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::FetchObjectRequest>(Arena*); template<> ::io::deephaven::proto::backplane::grpc::FetchObjectResponse* Arena::CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::FetchObjectResponse>(Arena*); +template<> ::io::deephaven::proto::backplane::grpc::StreamRequest* Arena::CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::StreamRequest>(Arena*); +template<> ::io::deephaven::proto::backplane::grpc::StreamResponse* Arena::CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::StreamResponse>(Arena*); PROTOBUF_NAMESPACE_CLOSE namespace io { namespace deephaven { @@ -344,27 +365,27 @@ class FetchObjectResponse final : // accessors ------------------------------------------------------- enum : int { - kTypedExportIdFieldNumber = 3, + kTypedExportIdsFieldNumber = 3, kTypeFieldNumber = 1, kDataFieldNumber = 2, }; - // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_id = 3; - int typed_export_id_size() const; + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_ids = 3; + int typed_export_ids_size() const; private: - int _internal_typed_export_id_size() const; + int _internal_typed_export_ids_size() const; public: - void clear_typed_export_id(); - ::io::deephaven::proto::backplane::grpc::TypedTicket* mutable_typed_export_id(int index); + void clear_typed_export_ids(); + ::io::deephaven::proto::backplane::grpc::TypedTicket* mutable_typed_export_ids(int index); ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >* - mutable_typed_export_id(); + mutable_typed_export_ids(); private: - const ::io::deephaven::proto::backplane::grpc::TypedTicket& _internal_typed_export_id(int index) const; - ::io::deephaven::proto::backplane::grpc::TypedTicket* _internal_add_typed_export_id(); + const ::io::deephaven::proto::backplane::grpc::TypedTicket& _internal_typed_export_ids(int index) const; + ::io::deephaven::proto::backplane::grpc::TypedTicket* _internal_add_typed_export_ids(); public: - const ::io::deephaven::proto::backplane::grpc::TypedTicket& typed_export_id(int index) const; - ::io::deephaven::proto::backplane::grpc::TypedTicket* add_typed_export_id(); + const ::io::deephaven::proto::backplane::grpc::TypedTicket& typed_export_ids(int index) const; + ::io::deephaven::proto::backplane::grpc::TypedTicket* add_typed_export_ids(); const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >& - typed_export_id() const; + typed_export_ids() const; // string type = 1; void clear_type(); @@ -401,12 +422,808 @@ class FetchObjectResponse final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket > typed_export_id_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket > typed_export_ids_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr data_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_deephaven_2fproto_2fobject_2eproto; }; +// ------------------------------------------------------------------- + +class ConnectRequest final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:io.deephaven.proto.backplane.grpc.ConnectRequest) */ { + public: + inline ConnectRequest() : ConnectRequest(nullptr) {} + ~ConnectRequest() override; + explicit PROTOBUF_CONSTEXPR ConnectRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + ConnectRequest(const ConnectRequest& from); + ConnectRequest(ConnectRequest&& from) noexcept + : ConnectRequest() { + *this = ::std::move(from); + } + + inline ConnectRequest& operator=(const ConnectRequest& from) { + CopyFrom(from); + return *this; + } + inline ConnectRequest& operator=(ConnectRequest&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const ConnectRequest& default_instance() { + return *internal_default_instance(); + } + static inline const ConnectRequest* internal_default_instance() { + return reinterpret_cast( + &_ConnectRequest_default_instance_); + } + static constexpr int kIndexInFileMessages = + 2; + + friend void swap(ConnectRequest& a, ConnectRequest& b) { + a.Swap(&b); + } + inline void Swap(ConnectRequest* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(ConnectRequest* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + ConnectRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const ConnectRequest& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const ConnectRequest& from); + private: + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(ConnectRequest* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "io.deephaven.proto.backplane.grpc.ConnectRequest"; + } + protected: + explicit ConnectRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kSourceIdFieldNumber = 1, + }; + // .io.deephaven.proto.backplane.grpc.TypedTicket source_id = 1; + bool has_source_id() const; + private: + bool _internal_has_source_id() const; + public: + void clear_source_id(); + const ::io::deephaven::proto::backplane::grpc::TypedTicket& source_id() const; + PROTOBUF_NODISCARD ::io::deephaven::proto::backplane::grpc::TypedTicket* release_source_id(); + ::io::deephaven::proto::backplane::grpc::TypedTicket* mutable_source_id(); + void set_allocated_source_id(::io::deephaven::proto::backplane::grpc::TypedTicket* source_id); + private: + const ::io::deephaven::proto::backplane::grpc::TypedTicket& _internal_source_id() const; + ::io::deephaven::proto::backplane::grpc::TypedTicket* _internal_mutable_source_id(); + public: + void unsafe_arena_set_allocated_source_id( + ::io::deephaven::proto::backplane::grpc::TypedTicket* source_id); + ::io::deephaven::proto::backplane::grpc::TypedTicket* unsafe_arena_release_source_id(); + + // @@protoc_insertion_point(class_scope:io.deephaven.proto.backplane.grpc.ConnectRequest) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::io::deephaven::proto::backplane::grpc::TypedTicket* source_id_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_deephaven_2fproto_2fobject_2eproto; +}; +// ------------------------------------------------------------------- + +class Data final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:io.deephaven.proto.backplane.grpc.Data) */ { + public: + inline Data() : Data(nullptr) {} + ~Data() override; + explicit PROTOBUF_CONSTEXPR Data(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + Data(const Data& from); + Data(Data&& from) noexcept + : Data() { + *this = ::std::move(from); + } + + inline Data& operator=(const Data& from) { + CopyFrom(from); + return *this; + } + inline Data& operator=(Data&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const Data& default_instance() { + return *internal_default_instance(); + } + static inline const Data* internal_default_instance() { + return reinterpret_cast( + &_Data_default_instance_); + } + static constexpr int kIndexInFileMessages = + 3; + + friend void swap(Data& a, Data& b) { + a.Swap(&b); + } + inline void Swap(Data* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Data* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + Data* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const Data& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const Data& from); + private: + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Data* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "io.deephaven.proto.backplane.grpc.Data"; + } + protected: + explicit Data(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kExportedReferencesFieldNumber = 2, + kPayloadFieldNumber = 1, + }; + // repeated .io.deephaven.proto.backplane.grpc.TypedTicket exported_references = 2; + int exported_references_size() const; + private: + int _internal_exported_references_size() const; + public: + void clear_exported_references(); + ::io::deephaven::proto::backplane::grpc::TypedTicket* mutable_exported_references(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >* + mutable_exported_references(); + private: + const ::io::deephaven::proto::backplane::grpc::TypedTicket& _internal_exported_references(int index) const; + ::io::deephaven::proto::backplane::grpc::TypedTicket* _internal_add_exported_references(); + public: + const ::io::deephaven::proto::backplane::grpc::TypedTicket& exported_references(int index) const; + ::io::deephaven::proto::backplane::grpc::TypedTicket* add_exported_references(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >& + exported_references() const; + + // bytes payload = 1; + void clear_payload(); + const std::string& payload() const; + template + void set_payload(ArgT0&& arg0, ArgT... args); + std::string* mutable_payload(); + PROTOBUF_NODISCARD std::string* release_payload(); + void set_allocated_payload(std::string* payload); + private: + const std::string& _internal_payload() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_payload(const std::string& value); + std::string* _internal_mutable_payload(); + public: + + // @@protoc_insertion_point(class_scope:io.deephaven.proto.backplane.grpc.Data) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket > exported_references_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr payload_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_deephaven_2fproto_2fobject_2eproto; +}; +// ------------------------------------------------------------------- + +class StreamRequest final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:io.deephaven.proto.backplane.grpc.StreamRequest) */ { + public: + inline StreamRequest() : StreamRequest(nullptr) {} + ~StreamRequest() override; + explicit PROTOBUF_CONSTEXPR StreamRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + StreamRequest(const StreamRequest& from); + StreamRequest(StreamRequest&& from) noexcept + : StreamRequest() { + *this = ::std::move(from); + } + + inline StreamRequest& operator=(const StreamRequest& from) { + CopyFrom(from); + return *this; + } + inline StreamRequest& operator=(StreamRequest&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const StreamRequest& default_instance() { + return *internal_default_instance(); + } + enum MessageCase { + kConnect = 1, + kData = 2, + MESSAGE_NOT_SET = 0, + }; + + static inline const StreamRequest* internal_default_instance() { + return reinterpret_cast( + &_StreamRequest_default_instance_); + } + static constexpr int kIndexInFileMessages = + 4; + + friend void swap(StreamRequest& a, StreamRequest& b) { + a.Swap(&b); + } + inline void Swap(StreamRequest* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(StreamRequest* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + StreamRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const StreamRequest& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const StreamRequest& from); + private: + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(StreamRequest* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "io.deephaven.proto.backplane.grpc.StreamRequest"; + } + protected: + explicit StreamRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kConnectFieldNumber = 1, + kDataFieldNumber = 2, + }; + // .io.deephaven.proto.backplane.grpc.ConnectRequest connect = 1; + bool has_connect() const; + private: + bool _internal_has_connect() const; + public: + void clear_connect(); + const ::io::deephaven::proto::backplane::grpc::ConnectRequest& connect() const; + PROTOBUF_NODISCARD ::io::deephaven::proto::backplane::grpc::ConnectRequest* release_connect(); + ::io::deephaven::proto::backplane::grpc::ConnectRequest* mutable_connect(); + void set_allocated_connect(::io::deephaven::proto::backplane::grpc::ConnectRequest* connect); + private: + const ::io::deephaven::proto::backplane::grpc::ConnectRequest& _internal_connect() const; + ::io::deephaven::proto::backplane::grpc::ConnectRequest* _internal_mutable_connect(); + public: + void unsafe_arena_set_allocated_connect( + ::io::deephaven::proto::backplane::grpc::ConnectRequest* connect); + ::io::deephaven::proto::backplane::grpc::ConnectRequest* unsafe_arena_release_connect(); + + // .io.deephaven.proto.backplane.grpc.Data data = 2; + bool has_data() const; + private: + bool _internal_has_data() const; + public: + void clear_data(); + const ::io::deephaven::proto::backplane::grpc::Data& data() const; + PROTOBUF_NODISCARD ::io::deephaven::proto::backplane::grpc::Data* release_data(); + ::io::deephaven::proto::backplane::grpc::Data* mutable_data(); + void set_allocated_data(::io::deephaven::proto::backplane::grpc::Data* data); + private: + const ::io::deephaven::proto::backplane::grpc::Data& _internal_data() const; + ::io::deephaven::proto::backplane::grpc::Data* _internal_mutable_data(); + public: + void unsafe_arena_set_allocated_data( + ::io::deephaven::proto::backplane::grpc::Data* data); + ::io::deephaven::proto::backplane::grpc::Data* unsafe_arena_release_data(); + + void clear_message(); + MessageCase message_case() const; + // @@protoc_insertion_point(class_scope:io.deephaven.proto.backplane.grpc.StreamRequest) + private: + class _Internal; + void set_has_connect(); + void set_has_data(); + + inline bool has_message() const; + inline void clear_has_message(); + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + union MessageUnion { + constexpr MessageUnion() : _constinit_{} {} + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized _constinit_; + ::io::deephaven::proto::backplane::grpc::ConnectRequest* connect_; + ::io::deephaven::proto::backplane::grpc::Data* data_; + } message_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + uint32_t _oneof_case_[1]; + + friend struct ::TableStruct_deephaven_2fproto_2fobject_2eproto; +}; +// ------------------------------------------------------------------- + +class StreamResponse final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:io.deephaven.proto.backplane.grpc.StreamResponse) */ { + public: + inline StreamResponse() : StreamResponse(nullptr) {} + ~StreamResponse() override; + explicit PROTOBUF_CONSTEXPR StreamResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + StreamResponse(const StreamResponse& from); + StreamResponse(StreamResponse&& from) noexcept + : StreamResponse() { + *this = ::std::move(from); + } + + inline StreamResponse& operator=(const StreamResponse& from) { + CopyFrom(from); + return *this; + } + inline StreamResponse& operator=(StreamResponse&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const StreamResponse& default_instance() { + return *internal_default_instance(); + } + enum MessageCase { + kData = 1, + MESSAGE_NOT_SET = 0, + }; + + static inline const StreamResponse* internal_default_instance() { + return reinterpret_cast( + &_StreamResponse_default_instance_); + } + static constexpr int kIndexInFileMessages = + 5; + + friend void swap(StreamResponse& a, StreamResponse& b) { + a.Swap(&b); + } + inline void Swap(StreamResponse* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(StreamResponse* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + StreamResponse* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const StreamResponse& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom(const StreamResponse& from); + private: + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(StreamResponse* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "io.deephaven.proto.backplane.grpc.StreamResponse"; + } + protected: + explicit StreamResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kDataFieldNumber = 1, + }; + // .io.deephaven.proto.backplane.grpc.Data data = 1; + bool has_data() const; + private: + bool _internal_has_data() const; + public: + void clear_data(); + const ::io::deephaven::proto::backplane::grpc::Data& data() const; + PROTOBUF_NODISCARD ::io::deephaven::proto::backplane::grpc::Data* release_data(); + ::io::deephaven::proto::backplane::grpc::Data* mutable_data(); + void set_allocated_data(::io::deephaven::proto::backplane::grpc::Data* data); + private: + const ::io::deephaven::proto::backplane::grpc::Data& _internal_data() const; + ::io::deephaven::proto::backplane::grpc::Data* _internal_mutable_data(); + public: + void unsafe_arena_set_allocated_data( + ::io::deephaven::proto::backplane::grpc::Data* data); + ::io::deephaven::proto::backplane::grpc::Data* unsafe_arena_release_data(); + + void clear_message(); + MessageCase message_case() const; + // @@protoc_insertion_point(class_scope:io.deephaven.proto.backplane.grpc.StreamResponse) + private: + class _Internal; + void set_has_data(); + + inline bool has_message() const; + inline void clear_has_message(); + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + union MessageUnion { + constexpr MessageUnion() : _constinit_{} {} + ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized _constinit_; + ::io::deephaven::proto::backplane::grpc::Data* data_; + } message_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + uint32_t _oneof_case_[1]; + + friend struct ::TableStruct_deephaven_2fproto_2fobject_2eproto; +}; +// ------------------------------------------------------------------- + +class BrowserNextResponse final : + public ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase /* @@protoc_insertion_point(class_definition:io.deephaven.proto.backplane.grpc.BrowserNextResponse) */ { + public: + inline BrowserNextResponse() : BrowserNextResponse(nullptr) {} + explicit PROTOBUF_CONSTEXPR BrowserNextResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + BrowserNextResponse(const BrowserNextResponse& from); + BrowserNextResponse(BrowserNextResponse&& from) noexcept + : BrowserNextResponse() { + *this = ::std::move(from); + } + + inline BrowserNextResponse& operator=(const BrowserNextResponse& from) { + CopyFrom(from); + return *this; + } + inline BrowserNextResponse& operator=(BrowserNextResponse&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const BrowserNextResponse& default_instance() { + return *internal_default_instance(); + } + static inline const BrowserNextResponse* internal_default_instance() { + return reinterpret_cast( + &_BrowserNextResponse_default_instance_); + } + static constexpr int kIndexInFileMessages = + 6; + + friend void swap(BrowserNextResponse& a, BrowserNextResponse& b) { + a.Swap(&b); + } + inline void Swap(BrowserNextResponse* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(BrowserNextResponse* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + BrowserNextResponse* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyFrom; + inline void CopyFrom(const BrowserNextResponse& from) { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::CopyImpl(this, from); + } + using ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeFrom; + void MergeFrom(const BrowserNextResponse& from) { + ::PROTOBUF_NAMESPACE_ID::internal::ZeroFieldsBase::MergeImpl(this, from); + } + public: + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "io.deephaven.proto.backplane.grpc.BrowserNextResponse"; + } + protected: + explicit BrowserNextResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:io.deephaven.proto.backplane.grpc.BrowserNextResponse) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + friend struct ::TableStruct_deephaven_2fproto_2fobject_2eproto; +}; // =================================================================== @@ -607,48 +1424,490 @@ inline void FetchObjectResponse::set_allocated_data(std::string* data) { // @@protoc_insertion_point(field_set_allocated:io.deephaven.proto.backplane.grpc.FetchObjectResponse.data) } -// repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_id = 3; -inline int FetchObjectResponse::_internal_typed_export_id_size() const { - return typed_export_id_.size(); +// repeated .io.deephaven.proto.backplane.grpc.TypedTicket typed_export_ids = 3; +inline int FetchObjectResponse::_internal_typed_export_ids_size() const { + return typed_export_ids_.size(); +} +inline int FetchObjectResponse::typed_export_ids_size() const { + return _internal_typed_export_ids_size(); +} +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* FetchObjectResponse::mutable_typed_export_ids(int index) { + // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_ids) + return typed_export_ids_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >* +FetchObjectResponse::mutable_typed_export_ids() { + // @@protoc_insertion_point(field_mutable_list:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_ids) + return &typed_export_ids_; +} +inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& FetchObjectResponse::_internal_typed_export_ids(int index) const { + return typed_export_ids_.Get(index); +} +inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& FetchObjectResponse::typed_export_ids(int index) const { + // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_ids) + return _internal_typed_export_ids(index); +} +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* FetchObjectResponse::_internal_add_typed_export_ids() { + return typed_export_ids_.Add(); +} +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* FetchObjectResponse::add_typed_export_ids() { + ::io::deephaven::proto::backplane::grpc::TypedTicket* _add = _internal_add_typed_export_ids(); + // @@protoc_insertion_point(field_add:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_ids) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >& +FetchObjectResponse::typed_export_ids() const { + // @@protoc_insertion_point(field_list:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_ids) + return typed_export_ids_; +} + +// ------------------------------------------------------------------- + +// ConnectRequest + +// .io.deephaven.proto.backplane.grpc.TypedTicket source_id = 1; +inline bool ConnectRequest::_internal_has_source_id() const { + return this != internal_default_instance() && source_id_ != nullptr; +} +inline bool ConnectRequest::has_source_id() const { + return _internal_has_source_id(); +} +inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& ConnectRequest::_internal_source_id() const { + const ::io::deephaven::proto::backplane::grpc::TypedTicket* p = source_id_; + return p != nullptr ? *p : reinterpret_cast( + ::io::deephaven::proto::backplane::grpc::_TypedTicket_default_instance_); +} +inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& ConnectRequest::source_id() const { + // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.ConnectRequest.source_id) + return _internal_source_id(); +} +inline void ConnectRequest::unsafe_arena_set_allocated_source_id( + ::io::deephaven::proto::backplane::grpc::TypedTicket* source_id) { + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_id_); + } + source_id_ = source_id; + if (source_id) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:io.deephaven.proto.backplane.grpc.ConnectRequest.source_id) +} +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* ConnectRequest::release_source_id() { + + ::io::deephaven::proto::backplane::grpc::TypedTicket* temp = source_id_; + source_id_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return temp; +} +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* ConnectRequest::unsafe_arena_release_source_id() { + // @@protoc_insertion_point(field_release:io.deephaven.proto.backplane.grpc.ConnectRequest.source_id) + + ::io::deephaven::proto::backplane::grpc::TypedTicket* temp = source_id_; + source_id_ = nullptr; + return temp; +} +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* ConnectRequest::_internal_mutable_source_id() { + + if (source_id_ == nullptr) { + auto* p = CreateMaybeMessage<::io::deephaven::proto::backplane::grpc::TypedTicket>(GetArenaForAllocation()); + source_id_ = p; + } + return source_id_; +} +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* ConnectRequest::mutable_source_id() { + ::io::deephaven::proto::backplane::grpc::TypedTicket* _msg = _internal_mutable_source_id(); + // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.ConnectRequest.source_id) + return _msg; +} +inline void ConnectRequest::set_allocated_source_id(::io::deephaven::proto::backplane::grpc::TypedTicket* source_id) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_id_); + } + if (source_id) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena( + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_id)); + if (message_arena != submessage_arena) { + source_id = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, source_id, submessage_arena); + } + + } else { + + } + source_id_ = source_id; + // @@protoc_insertion_point(field_set_allocated:io.deephaven.proto.backplane.grpc.ConnectRequest.source_id) +} + +// ------------------------------------------------------------------- + +// Data + +// bytes payload = 1; +inline void Data::clear_payload() { + payload_.ClearToEmpty(); +} +inline const std::string& Data::payload() const { + // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.Data.payload) + return _internal_payload(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void Data::set_payload(ArgT0&& arg0, ArgT... args) { + + payload_.SetBytes(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:io.deephaven.proto.backplane.grpc.Data.payload) +} +inline std::string* Data::mutable_payload() { + std::string* _s = _internal_mutable_payload(); + // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.Data.payload) + return _s; +} +inline const std::string& Data::_internal_payload() const { + return payload_.Get(); +} +inline void Data::_internal_set_payload(const std::string& value) { + + payload_.Set(value, GetArenaForAllocation()); +} +inline std::string* Data::_internal_mutable_payload() { + + return payload_.Mutable(GetArenaForAllocation()); +} +inline std::string* Data::release_payload() { + // @@protoc_insertion_point(field_release:io.deephaven.proto.backplane.grpc.Data.payload) + return payload_.Release(); +} +inline void Data::set_allocated_payload(std::string* payload) { + if (payload != nullptr) { + + } else { + + } + payload_.SetAllocated(payload, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (payload_.IsDefault()) { + payload_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:io.deephaven.proto.backplane.grpc.Data.payload) +} + +// repeated .io.deephaven.proto.backplane.grpc.TypedTicket exported_references = 2; +inline int Data::_internal_exported_references_size() const { + return exported_references_.size(); } -inline int FetchObjectResponse::typed_export_id_size() const { - return _internal_typed_export_id_size(); +inline int Data::exported_references_size() const { + return _internal_exported_references_size(); } -inline ::io::deephaven::proto::backplane::grpc::TypedTicket* FetchObjectResponse::mutable_typed_export_id(int index) { - // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_id) - return typed_export_id_.Mutable(index); +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* Data::mutable_exported_references(int index) { + // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.Data.exported_references) + return exported_references_.Mutable(index); } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >* -FetchObjectResponse::mutable_typed_export_id() { - // @@protoc_insertion_point(field_mutable_list:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_id) - return &typed_export_id_; +Data::mutable_exported_references() { + // @@protoc_insertion_point(field_mutable_list:io.deephaven.proto.backplane.grpc.Data.exported_references) + return &exported_references_; } -inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& FetchObjectResponse::_internal_typed_export_id(int index) const { - return typed_export_id_.Get(index); +inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& Data::_internal_exported_references(int index) const { + return exported_references_.Get(index); } -inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& FetchObjectResponse::typed_export_id(int index) const { - // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_id) - return _internal_typed_export_id(index); +inline const ::io::deephaven::proto::backplane::grpc::TypedTicket& Data::exported_references(int index) const { + // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.Data.exported_references) + return _internal_exported_references(index); } -inline ::io::deephaven::proto::backplane::grpc::TypedTicket* FetchObjectResponse::_internal_add_typed_export_id() { - return typed_export_id_.Add(); +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* Data::_internal_add_exported_references() { + return exported_references_.Add(); } -inline ::io::deephaven::proto::backplane::grpc::TypedTicket* FetchObjectResponse::add_typed_export_id() { - ::io::deephaven::proto::backplane::grpc::TypedTicket* _add = _internal_add_typed_export_id(); - // @@protoc_insertion_point(field_add:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_id) +inline ::io::deephaven::proto::backplane::grpc::TypedTicket* Data::add_exported_references() { + ::io::deephaven::proto::backplane::grpc::TypedTicket* _add = _internal_add_exported_references(); + // @@protoc_insertion_point(field_add:io.deephaven.proto.backplane.grpc.Data.exported_references) return _add; } inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::io::deephaven::proto::backplane::grpc::TypedTicket >& -FetchObjectResponse::typed_export_id() const { - // @@protoc_insertion_point(field_list:io.deephaven.proto.backplane.grpc.FetchObjectResponse.typed_export_id) - return typed_export_id_; +Data::exported_references() const { + // @@protoc_insertion_point(field_list:io.deephaven.proto.backplane.grpc.Data.exported_references) + return exported_references_; +} + +// ------------------------------------------------------------------- + +// StreamRequest + +// .io.deephaven.proto.backplane.grpc.ConnectRequest connect = 1; +inline bool StreamRequest::_internal_has_connect() const { + return message_case() == kConnect; +} +inline bool StreamRequest::has_connect() const { + return _internal_has_connect(); +} +inline void StreamRequest::set_has_connect() { + _oneof_case_[0] = kConnect; +} +inline void StreamRequest::clear_connect() { + if (_internal_has_connect()) { + if (GetArenaForAllocation() == nullptr) { + delete message_.connect_; + } + clear_has_message(); + } +} +inline ::io::deephaven::proto::backplane::grpc::ConnectRequest* StreamRequest::release_connect() { + // @@protoc_insertion_point(field_release:io.deephaven.proto.backplane.grpc.StreamRequest.connect) + if (_internal_has_connect()) { + clear_has_message(); + ::io::deephaven::proto::backplane::grpc::ConnectRequest* temp = message_.connect_; + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + message_.connect_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline const ::io::deephaven::proto::backplane::grpc::ConnectRequest& StreamRequest::_internal_connect() const { + return _internal_has_connect() + ? *message_.connect_ + : reinterpret_cast< ::io::deephaven::proto::backplane::grpc::ConnectRequest&>(::io::deephaven::proto::backplane::grpc::_ConnectRequest_default_instance_); +} +inline const ::io::deephaven::proto::backplane::grpc::ConnectRequest& StreamRequest::connect() const { + // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.StreamRequest.connect) + return _internal_connect(); +} +inline ::io::deephaven::proto::backplane::grpc::ConnectRequest* StreamRequest::unsafe_arena_release_connect() { + // @@protoc_insertion_point(field_unsafe_arena_release:io.deephaven.proto.backplane.grpc.StreamRequest.connect) + if (_internal_has_connect()) { + clear_has_message(); + ::io::deephaven::proto::backplane::grpc::ConnectRequest* temp = message_.connect_; + message_.connect_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline void StreamRequest::unsafe_arena_set_allocated_connect(::io::deephaven::proto::backplane::grpc::ConnectRequest* connect) { + clear_message(); + if (connect) { + set_has_connect(); + message_.connect_ = connect; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:io.deephaven.proto.backplane.grpc.StreamRequest.connect) +} +inline ::io::deephaven::proto::backplane::grpc::ConnectRequest* StreamRequest::_internal_mutable_connect() { + if (!_internal_has_connect()) { + clear_message(); + set_has_connect(); + message_.connect_ = CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::ConnectRequest >(GetArenaForAllocation()); + } + return message_.connect_; +} +inline ::io::deephaven::proto::backplane::grpc::ConnectRequest* StreamRequest::mutable_connect() { + ::io::deephaven::proto::backplane::grpc::ConnectRequest* _msg = _internal_mutable_connect(); + // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.StreamRequest.connect) + return _msg; +} + +// .io.deephaven.proto.backplane.grpc.Data data = 2; +inline bool StreamRequest::_internal_has_data() const { + return message_case() == kData; +} +inline bool StreamRequest::has_data() const { + return _internal_has_data(); +} +inline void StreamRequest::set_has_data() { + _oneof_case_[0] = kData; +} +inline void StreamRequest::clear_data() { + if (_internal_has_data()) { + if (GetArenaForAllocation() == nullptr) { + delete message_.data_; + } + clear_has_message(); + } +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamRequest::release_data() { + // @@protoc_insertion_point(field_release:io.deephaven.proto.backplane.grpc.StreamRequest.data) + if (_internal_has_data()) { + clear_has_message(); + ::io::deephaven::proto::backplane::grpc::Data* temp = message_.data_; + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + message_.data_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline const ::io::deephaven::proto::backplane::grpc::Data& StreamRequest::_internal_data() const { + return _internal_has_data() + ? *message_.data_ + : reinterpret_cast< ::io::deephaven::proto::backplane::grpc::Data&>(::io::deephaven::proto::backplane::grpc::_Data_default_instance_); +} +inline const ::io::deephaven::proto::backplane::grpc::Data& StreamRequest::data() const { + // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.StreamRequest.data) + return _internal_data(); +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamRequest::unsafe_arena_release_data() { + // @@protoc_insertion_point(field_unsafe_arena_release:io.deephaven.proto.backplane.grpc.StreamRequest.data) + if (_internal_has_data()) { + clear_has_message(); + ::io::deephaven::proto::backplane::grpc::Data* temp = message_.data_; + message_.data_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline void StreamRequest::unsafe_arena_set_allocated_data(::io::deephaven::proto::backplane::grpc::Data* data) { + clear_message(); + if (data) { + set_has_data(); + message_.data_ = data; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:io.deephaven.proto.backplane.grpc.StreamRequest.data) +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamRequest::_internal_mutable_data() { + if (!_internal_has_data()) { + clear_message(); + set_has_data(); + message_.data_ = CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::Data >(GetArenaForAllocation()); + } + return message_.data_; +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamRequest::mutable_data() { + ::io::deephaven::proto::backplane::grpc::Data* _msg = _internal_mutable_data(); + // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.StreamRequest.data) + return _msg; +} + +inline bool StreamRequest::has_message() const { + return message_case() != MESSAGE_NOT_SET; +} +inline void StreamRequest::clear_has_message() { + _oneof_case_[0] = MESSAGE_NOT_SET; +} +inline StreamRequest::MessageCase StreamRequest::message_case() const { + return StreamRequest::MessageCase(_oneof_case_[0]); +} +// ------------------------------------------------------------------- + +// StreamResponse + +// .io.deephaven.proto.backplane.grpc.Data data = 1; +inline bool StreamResponse::_internal_has_data() const { + return message_case() == kData; +} +inline bool StreamResponse::has_data() const { + return _internal_has_data(); +} +inline void StreamResponse::set_has_data() { + _oneof_case_[0] = kData; +} +inline void StreamResponse::clear_data() { + if (_internal_has_data()) { + if (GetArenaForAllocation() == nullptr) { + delete message_.data_; + } + clear_has_message(); + } +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamResponse::release_data() { + // @@protoc_insertion_point(field_release:io.deephaven.proto.backplane.grpc.StreamResponse.data) + if (_internal_has_data()) { + clear_has_message(); + ::io::deephaven::proto::backplane::grpc::Data* temp = message_.data_; + if (GetArenaForAllocation() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + message_.data_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline const ::io::deephaven::proto::backplane::grpc::Data& StreamResponse::_internal_data() const { + return _internal_has_data() + ? *message_.data_ + : reinterpret_cast< ::io::deephaven::proto::backplane::grpc::Data&>(::io::deephaven::proto::backplane::grpc::_Data_default_instance_); +} +inline const ::io::deephaven::proto::backplane::grpc::Data& StreamResponse::data() const { + // @@protoc_insertion_point(field_get:io.deephaven.proto.backplane.grpc.StreamResponse.data) + return _internal_data(); +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamResponse::unsafe_arena_release_data() { + // @@protoc_insertion_point(field_unsafe_arena_release:io.deephaven.proto.backplane.grpc.StreamResponse.data) + if (_internal_has_data()) { + clear_has_message(); + ::io::deephaven::proto::backplane::grpc::Data* temp = message_.data_; + message_.data_ = nullptr; + return temp; + } else { + return nullptr; + } +} +inline void StreamResponse::unsafe_arena_set_allocated_data(::io::deephaven::proto::backplane::grpc::Data* data) { + clear_message(); + if (data) { + set_has_data(); + message_.data_ = data; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:io.deephaven.proto.backplane.grpc.StreamResponse.data) +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamResponse::_internal_mutable_data() { + if (!_internal_has_data()) { + clear_message(); + set_has_data(); + message_.data_ = CreateMaybeMessage< ::io::deephaven::proto::backplane::grpc::Data >(GetArenaForAllocation()); + } + return message_.data_; +} +inline ::io::deephaven::proto::backplane::grpc::Data* StreamResponse::mutable_data() { + ::io::deephaven::proto::backplane::grpc::Data* _msg = _internal_mutable_data(); + // @@protoc_insertion_point(field_mutable:io.deephaven.proto.backplane.grpc.StreamResponse.data) + return _msg; } +inline bool StreamResponse::has_message() const { + return message_case() != MESSAGE_NOT_SET; +} +inline void StreamResponse::clear_has_message() { + _oneof_case_[0] = MESSAGE_NOT_SET; +} +inline StreamResponse::MessageCase StreamResponse::message_case() const { + return StreamResponse::MessageCase(_oneof_case_[0]); +} +// ------------------------------------------------------------------- + +// BrowserNextResponse + #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // __GNUC__ // ------------------------------------------------------------------- +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + // @@protoc_insertion_point(namespace_scope) diff --git a/docker/registry/python/gradle.properties b/docker/registry/python/gradle.properties index 731d1d5e603..acb569993f7 100644 --- a/docker/registry/python/gradle.properties +++ b/docker/registry/python/gradle.properties @@ -1,3 +1,3 @@ io.deephaven.project.ProjectType=DOCKER_REGISTRY -deephaven.registry.imageName=python:3.7 -deephaven.registry.imageId=python@sha256:6eae21f868957a5d2ae559dc639474482770d37d48d33377de6a69c7e7fb4eab +deephaven.registry.imageName=python:3.10 +deephaven.registry.imageId=python@sha256:74cdd039dc36f6476dd5dfdbc187830e0c0f760a1bdfc73d186060ef4c4bd78f diff --git a/docker/registry/server-base/gradle.properties b/docker/registry/server-base/gradle.properties index ff42f2d55e1..14b2e0ca5fe 100644 --- a/docker/registry/server-base/gradle.properties +++ b/docker/registry/server-base/gradle.properties @@ -1,3 +1,3 @@ io.deephaven.project.ProjectType=DOCKER_REGISTRY deephaven.registry.imageName=ghcr.io/deephaven/server-base:edge -deephaven.registry.imageId=ghcr.io/deephaven/server-base@sha256:2aa7e285c998223cc5f1b53819052f62e9b7e567237b33915547486f9d0878d5 +deephaven.registry.imageId=ghcr.io/deephaven/server-base@sha256:89b11b535ed67027d4370a95fd37d348ca472ee0ee987aea6804c6ee4620fbd2 diff --git a/docker/registry/slim-base/gradle.properties b/docker/registry/slim-base/gradle.properties index bdae35a1e88..f32d672ac22 100644 --- a/docker/registry/slim-base/gradle.properties +++ b/docker/registry/slim-base/gradle.properties @@ -1,3 +1,3 @@ io.deephaven.project.ProjectType=DOCKER_REGISTRY deephaven.registry.imageName=ghcr.io/deephaven/server-slim-base:edge -deephaven.registry.imageId=ghcr.io/deephaven/server-slim-base@sha256:a0f9010fb99fb85deb9ffe379cf818a904311db3d45001882bc9938851a31c7d +deephaven.registry.imageId=ghcr.io/deephaven/server-slim-base@sha256:9e8b61362bb60e9797c9939b4955c5a3b01a228e2d1b3b2d9f461c0729c805a5 diff --git a/docker/server-jetty/src/main/server-jetty/requirements.txt b/docker/server-jetty/src/main/server-jetty/requirements.txt index 2bb99fdc0bb..045f63d7589 100644 --- a/docker/server-jetty/src/main/server-jetty/requirements.txt +++ b/docker/server-jetty/src/main/server-jetty/requirements.txt @@ -1,7 +1,7 @@ adbc-driver-manager==0.5.1 adbc-driver-postgresql==0.5.1 connectorx==0.3.1; platform.machine == 'x86_64' -deephaven-plugin==0.3.0 +deephaven-plugin==0.5.0 java-utilities==0.2.0 jedi==0.18.2 jpy==0.14.0 diff --git a/docker/server/src/main/server-netty/requirements.txt b/docker/server/src/main/server-netty/requirements.txt index 2bb99fdc0bb..045f63d7589 100644 --- a/docker/server/src/main/server-netty/requirements.txt +++ b/docker/server/src/main/server-netty/requirements.txt @@ -1,7 +1,7 @@ adbc-driver-manager==0.5.1 adbc-driver-postgresql==0.5.1 connectorx==0.3.1; platform.machine == 'x86_64' -deephaven-plugin==0.3.0 +deephaven-plugin==0.5.0 java-utilities==0.2.0 jedi==0.18.2 jpy==0.14.0 diff --git a/java-client/session/src/main/java/io/deephaven/client/impl/SessionImpl.java b/java-client/session/src/main/java/io/deephaven/client/impl/SessionImpl.java index 2f931e4cac0..390b8a28fa5 100644 --- a/java-client/session/src/main/java/io/deephaven/client/impl/SessionImpl.java +++ b/java-client/session/src/main/java/io/deephaven/client/impl/SessionImpl.java @@ -181,7 +181,7 @@ public CompletableFuture fetchObject(String type, HasTicketId tic response -> { final String responseType = response.getType(); final ByteString data = response.getData(); - final List exportIds = response.getTypedExportIdList().stream() + final List exportIds = response.getTypedExportIdsList().stream() .map(t -> { final String ticketType; if (t.getType().isEmpty()) { diff --git a/plugin/dagger/src/test/java/io/deephaven/plugin/PluginModuleTest.java b/plugin/dagger/src/test/java/io/deephaven/plugin/PluginModuleTest.java index ca308bd387c..ff1b0a38bc7 100644 --- a/plugin/dagger/src/test/java/io/deephaven/plugin/PluginModuleTest.java +++ b/plugin/dagger/src/test/java/io/deephaven/plugin/PluginModuleTest.java @@ -8,6 +8,7 @@ import dagger.Component; import dagger.Module; import dagger.multibindings.IntoSet; +import io.deephaven.plugin.type.Exporter; import io.deephaven.plugin.type.ObjectType; import io.deephaven.plugin.type.ObjectTypeBase; import org.junit.jupiter.api.Test; @@ -82,7 +83,7 @@ public > T walk(V visitor) { } @AutoService(ObjectType.class) - public static class AutoObjectType extends ObjectTypeBase { + public static class AutoObjectType extends ObjectTypeBase.FetchOnly { public AutoObjectType() {} @@ -122,7 +123,7 @@ public > T walk(V visitor) { } } - public static class BoundObjectType extends ObjectTypeBase { + public static class BoundObjectType extends ObjectTypeBase.FetchOnly { @Inject public BoundObjectType() {} @@ -152,7 +153,7 @@ public > T walk(V visitor) { } } - public static class BadObjectType extends ObjectTypeBase { + public static class BadObjectType extends ObjectTypeBase.FetchOnly { @Inject public BadObjectType() {} diff --git a/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTranslator.java b/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTranslator.java index 427735e2c93..63fc8cd57e2 100644 --- a/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTranslator.java +++ b/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTranslator.java @@ -39,8 +39,8 @@ import io.deephaven.plot.util.PlotUtils; import io.deephaven.plot.util.tables.*; import io.deephaven.plot.util.tables.PartitionedTableHandle; -import io.deephaven.plugin.type.ObjectType.Exporter; -import io.deephaven.plugin.type.ObjectType.Exporter.Reference; +import io.deephaven.plugin.type.Exporter; +import io.deephaven.plugin.type.Exporter.Reference; import io.deephaven.proto.backplane.script.grpc.FigureDescriptor; import io.deephaven.proto.backplane.script.grpc.FigureDescriptor.AxisDescriptor; import io.deephaven.proto.backplane.script.grpc.FigureDescriptor.BoolMapWithDefault; @@ -109,7 +109,7 @@ private FigureDescriptor translateFigure(FigureWidget f, Exporter exporter) { i++; // noinspection unused - final Reference reference = exporter.reference(table, false, true).orElseThrow(); + final Reference reference = exporter.reference(table); // relying on FetchObjectResponse.export_id for communicating exported tables to the client } @@ -129,7 +129,7 @@ private FigureDescriptor translateFigure(FigureWidget f, Exporter exporter) { } i++; - exporter.reference(partitionedTable, false, true).orElseThrow(); + exporter.reference(partitionedTable); } assignOptionalField(figure.getTitle(), clientFigure::setTitle, clientFigure::clearTitle); diff --git a/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTypePlugin.java b/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTypePlugin.java index d08ff4f8a1d..ccb39a2702e 100644 --- a/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTypePlugin.java +++ b/plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTypePlugin.java @@ -5,6 +5,7 @@ import com.google.auto.service.AutoService; import io.deephaven.plot.FigureWidget; +import io.deephaven.plugin.type.Exporter; import io.deephaven.plugin.type.ObjectType; import io.deephaven.plugin.type.ObjectTypeClassBase; @@ -15,7 +16,7 @@ * An object type named {@value NAME} of java class type {@link FigureWidget}. */ @AutoService(ObjectType.class) -public final class FigureWidgetTypePlugin extends ObjectTypeClassBase { +public final class FigureWidgetTypePlugin extends ObjectTypeClassBase.FetchOnly { public static final String NAME = "Figure"; diff --git a/plugin/hierarchicaltable/src/main/java/io/deephaven/hierarchicaltable/HierarchicalTableTypePlugin.java b/plugin/hierarchicaltable/src/main/java/io/deephaven/hierarchicaltable/HierarchicalTableTypePlugin.java index 36b69c35d4d..381647d1b21 100644 --- a/plugin/hierarchicaltable/src/main/java/io/deephaven/hierarchicaltable/HierarchicalTableTypePlugin.java +++ b/plugin/hierarchicaltable/src/main/java/io/deephaven/hierarchicaltable/HierarchicalTableTypePlugin.java @@ -5,10 +5,9 @@ import com.google.auto.service.AutoService; import io.deephaven.engine.table.hierarchical.HierarchicalTable; -import io.deephaven.engine.table.hierarchical.RollupTable; -import io.deephaven.engine.table.hierarchical.TreeTable; import io.deephaven.extensions.barrage.util.BarrageUtil; import io.deephaven.extensions.barrage.util.HierarchicalTableSchemaUtil; +import io.deephaven.plugin.type.Exporter; import io.deephaven.plugin.type.ObjectType; import io.deephaven.plugin.type.ObjectTypeBase; import io.deephaven.proto.backplane.grpc.HierarchicalTableDescriptor; @@ -21,7 +20,7 @@ * An object type named {@value #NAME} of java class type {@link HierarchicalTable}. */ @AutoService(ObjectType.class) -public class HierarchicalTableTypePlugin extends ObjectTypeBase { +public class HierarchicalTableTypePlugin extends ObjectTypeBase.FetchOnly { private static final String NAME = "HierarchicalTable"; diff --git a/plugin/partitionedtable/src/main/java/io/deephaven/partitionedtable/PartitionedTableTypePlugin.java b/plugin/partitionedtable/src/main/java/io/deephaven/partitionedtable/PartitionedTableTypePlugin.java index 183243a5cfa..57e32281d20 100644 --- a/plugin/partitionedtable/src/main/java/io/deephaven/partitionedtable/PartitionedTableTypePlugin.java +++ b/plugin/partitionedtable/src/main/java/io/deephaven/partitionedtable/PartitionedTableTypePlugin.java @@ -4,6 +4,7 @@ import com.google.protobuf.ByteString; import io.deephaven.engine.table.PartitionedTable; import io.deephaven.extensions.barrage.util.BarrageUtil; +import io.deephaven.plugin.type.Exporter; import io.deephaven.plugin.type.ObjectType; import io.deephaven.plugin.type.ObjectTypeBase; import io.deephaven.proto.backplane.grpc.PartitionedTableDescriptor; @@ -17,7 +18,7 @@ * a ticket to the underlying table that tracks the keys and the actual table objects. */ @AutoService(ObjectType.class) -public class PartitionedTableTypePlugin extends ObjectTypeBase { +public class PartitionedTableTypePlugin extends ObjectTypeBase.FetchOnly { @Override public String name() { @@ -32,7 +33,7 @@ public boolean isType(Object object) { @Override public void writeCompatibleObjectTo(Exporter exporter, Object object, OutputStream out) throws IOException { PartitionedTable partitionedTable = (PartitionedTable) object; - exporter.reference(partitionedTable.table(), false, true); + exporter.reference(partitionedTable.table()); // Send Schema wrapped in Message ByteString schemaWrappedInMessage = BarrageUtil.schemaBytesFromTableDefinition( diff --git a/plugin/src/main/java/io/deephaven/plugin/type/Exporter.java b/plugin/src/main/java/io/deephaven/plugin/type/Exporter.java new file mode 100644 index 00000000000..48e8bee4c99 --- /dev/null +++ b/plugin/src/main/java/io/deephaven/plugin/type/Exporter.java @@ -0,0 +1,113 @@ +package io.deephaven.plugin.type; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.BiPredicate; + +/** + * Utility to export objects while writing a payload to send to the client. + */ +public class Exporter { + private final List references = new ArrayList<>(); + private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + /** + * Gets the reference for {@code object} if it has already been created and {@code forceNew} is {@code false}, + * otherwise creates a new one. If {@code allowUnknownType} is {@code false}, and no type can be found, no reference + * will be created. Uses reference-based equality. + * + * @deprecated Please use {@link #reference(Object)} instead - as of 0.27.0, the parameters allowUnknownType and + * forceNew can only be set to true going forward. + * + * @param object the object + * @param allowUnknownType if an unknown-typed reference can be created + * @param forceNew if a new reference should be created + * @return the reference + */ + @Deprecated(since = "0.27.0") + public Optional reference(Object object, boolean allowUnknownType, boolean forceNew) { + return reference(object, allowUnknownType, forceNew, Object::equals); + } + + /** + * Gets the reference for {@code object} if it has already been created and {@code forceNew} is {@code false}, + * otherwise creates a new one. If {@code allowUnknownType} is {@code false}, and no type can be found, no reference + * will be created. + * + * @deprecated Please use {@link #reference(Object)} instead - as of 0.27.0, the parameters allowUnknownType and + * forceNew can only be set to true going forward. + * + * @param object the object + * @param allowUnknownType if an unknown-typed reference can be created + * @param forceNew if a new reference should be created + * @param equals the equals logic - unused. + * @return the reference + */ + @Deprecated(since = "0.27.0") + public Optional reference(Object object, boolean allowUnknownType, boolean forceNew, + BiPredicate equals) { + if (!allowUnknownType) { + throw new IllegalArgumentException("allowUnknownType must be true"); + } + if (!forceNew) { + throw new IllegalArgumentException("forceNew must be true"); + } + int index = references.size(); + references.add(object); + + return Optional.of(() -> index); + } + + public OutputStream outputStream() { + return outputStream; + } + + public ByteBuffer payload() { + return ByteBuffer.wrap(outputStream.toByteArray()); + } + + public Object[] references() { + return references.toArray(); + } + + /** + * Creates a new reference for the provided object. A reference will be created and the object exported even if the + * object has no corresponding plugin provided, granting the client the ability to reference the object on later + * calls, and requiring that they release it when no longer needed. + * + * @param object the object + * @return the reference + */ + public Reference reference(Object object) { + // noinspection OptionalGetWithoutIsPresent + return reference(object, true, true).get(); + } + + /** + * A reference. + */ + public interface Reference { + /** + * The index, which is defined by the order in which references are created. May be used in the output stream to + * refer to the reference from the client. + * + * @return the index + */ + int index(); + + /** + * The type. + * + * @deprecated As of 0.27.0, this will always return empty. + * @return the type, if present + */ + @Deprecated(since = "0.27.0") + default Optional type() { + return Optional.empty(); + } + } +} diff --git a/plugin/src/main/java/io/deephaven/plugin/type/ObjectCommunicationException.java b/plugin/src/main/java/io/deephaven/plugin/type/ObjectCommunicationException.java new file mode 100644 index 00000000000..1cfcac40209 --- /dev/null +++ b/plugin/src/main/java/io/deephaven/plugin/type/ObjectCommunicationException.java @@ -0,0 +1,23 @@ +package io.deephaven.plugin.type; + +/** + * Thrown when errors occur when communicating with the client. This is a checked exception to ensure it doesn't escape + * to somewhere that could crash part of the server. + */ +public class ObjectCommunicationException extends Exception { + public ObjectCommunicationException() { + super(); + } + + public ObjectCommunicationException(String message) { + super(message); + } + + public ObjectCommunicationException(String message, Throwable cause) { + super(message, cause); + } + + public ObjectCommunicationException(Throwable cause) { + super(cause); + } +} diff --git a/plugin/src/main/java/io/deephaven/plugin/type/ObjectType.java b/plugin/src/main/java/io/deephaven/plugin/type/ObjectType.java index 04bca9d05f8..1538eb7401e 100644 --- a/plugin/src/main/java/io/deephaven/plugin/type/ObjectType.java +++ b/plugin/src/main/java/io/deephaven/plugin/type/ObjectType.java @@ -4,12 +4,8 @@ package io.deephaven.plugin.type; import io.deephaven.plugin.Plugin; -import io.deephaven.plugin.type.ObjectType.Exporter.Reference; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Optional; -import java.util.function.BiPredicate; +import java.nio.ByteBuffer; /** * An "object type" plugin. Useful for serializing custom objects between the server / client. @@ -32,71 +28,59 @@ public interface ObjectType extends Plugin { boolean isType(Object object); /** - * Serializes {@code object} into {@code out}. Must only be called with a compatible object, see - * {@link #isType(Object)}. - * - *

- * Objects that {@code object} references may be serialized as {@link Reference}. - * - *

- * Note: the implementation should not hold onto references nor create references outside the calling thread. - * - * @param exporter the exporter - * @param object the (compatible) object - * @param out the output stream - * @throws IOException if an IO exception occurs + * A stream of messages, either sent from the server to the client, or client to the server. ObjectType plugin + * implementations provide an instance of this interface for each incoming stream to invoke as messages arrive, and + * will likewise be given an instance of this interface to be able to send messages to the client. */ - void writeTo(Exporter exporter, Object object, OutputStream out) throws IOException; - - /** - * The interface for creating new references during the {@link #writeTo(Exporter, Object, OutputStream)}. - */ - interface Exporter { - + interface MessageStream { /** - * Gets the reference for {@code object} if it has already been created and {@code forceNew} is {@code false}, - * otherwise creates a new one. If {@code allowUnknownType} is {@code false}, and no type can be found, no - * reference will be created. Uses reference-based equality. - * - * @param object the object - * @param allowUnknownType if an unknown-typed reference can be created - * @param forceNew if a new reference should be created - * @return the reference + * Simple stream that does no handling on data or close. */ - Optional reference(Object object, boolean allowUnknownType, boolean forceNew); + MessageStream NOOP = new MessageStream() { + @Override + public void onData(ByteBuffer payload, Object... references) {} + + @Override + public void onClose() {} + }; /** - * Gets the reference for {@code object} if it has already been created and {@code forceNew} is {@code false}, - * otherwise creates a new one. If {@code allowUnknownType} is {@code false}, and no type can be found, no - * reference will be created. + * Transmits/receives data to/from the remote end of the stream. This can consist of a binary payload and + * references to objects on the server. + *

+ *

+ * When implementing this interface for a plugin, this method will be invoked when a request arrives from the + * client. When invoking this method from in a plugin, it will send a response to the client. + *

+ *

+ * Note that sending a message can cause an exception if there is an error in serializing, and for that reason + * this method throws a checked exception. It is safe to let that propagate up through either an incoming + * {@link #onData onData call from a client}, or the {@link ObjectType#clientConnection(Object, MessageStream) + * call to create the stream}, but it is usually unsafe to let this propagate to other engine threads. * - * @param object the object - * @param allowUnknownType if an unknown-typed reference can be created - * @param forceNew if a new reference should be created - * @param equals the equals logic - * @return the reference + * @param payload the binary data sent to the remote implementation + * @param references server-side object references sent to the remote implementation + * @throws ObjectCommunicationException a checked exception for any errors that may occur, to ensure that the + * error is handled without propagating. */ - Optional reference(Object object, boolean allowUnknownType, boolean forceNew, - BiPredicate equals); + void onData(ByteBuffer payload, Object... references) throws ObjectCommunicationException; /** - * A reference. + * Closes the stream on both ends. No further messages can be sent or received. */ - interface Reference { - /** - * The index, which is defined by the order in which references are created. May be used in the output - * stream to refer to the reference from the client. - * - * @return the index - */ - int index(); - - /** - * The type. - * - * @return the type, if present - */ - Optional type(); - } + void onClose(); } + + /** + * Signals creation of a client stream to the provided object. The returned MessageStream implementation will be + * called with each received message from the client, and can call the provided connection instance to send messages + * as needed to the client. + * + * @param object the object to create a connection for + * @param connection a stream to send objects to the client + * @throws ObjectCommunicationException may throw an exception received from + * {@link MessageStream#onData(ByteBuffer, Object...)} calls + * @return a stream to receive objects from the client + */ + MessageStream clientConnection(Object object, MessageStream connection) throws ObjectCommunicationException; } diff --git a/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeBase.java b/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeBase.java index 95438ac5331..bea1c30da4a 100644 --- a/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeBase.java +++ b/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeBase.java @@ -7,21 +7,78 @@ import java.io.IOException; import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.ByteBuffer; +/** + * Abstract base class for object type plugins, providing some simple implementation details. + */ public abstract class ObjectTypeBase extends PluginBase implements ObjectType { - - public abstract void writeCompatibleObjectTo(Exporter exporter, Object object, OutputStream out) throws IOException; - @Override - public final void writeTo(Exporter exporter, Object object, OutputStream out) throws IOException { + public final MessageStream clientConnection(Object object, MessageStream connection) + throws ObjectCommunicationException { if (!isType(object)) { throw new IllegalArgumentException("Can't serialize object, wrong type: " + this + " / " + object); } - writeCompatibleObjectTo(exporter, object, out); + return compatibleClientConnection(object, connection); } + /** + * Signals creation of a client stream to the provided object. The returned MessageStream implementation will be + * called with each received message from the client, and can call the provided connection instance to send messages + * as needed to the client. + * + * @param object the object to create a connection for + * @param connection a stream to send objects to the client + * @throws ObjectCommunicationException may throw an exception received from + * {@link MessageStream#onData(ByteBuffer, Object...)} calls + * @return a stream to receive objects from the client + */ + public abstract MessageStream compatibleClientConnection(Object object, MessageStream connection) + throws ObjectCommunicationException; + @Override public final > T walk(V visitor) { return visitor.visit(this); } + + /** + * Abstract base class for object type plugins that can only be fetched (and will not have later responses or accept + * later requests). For bidirectional messages, see {@link ObjectTypeBase}. + */ + public abstract static class FetchOnly extends ObjectTypeBase { + + /** + * Serializes {@code object} as bytes to {@code out}. Must only be called with {@link #isType(Object) a + * compatible object}. + * + * Server-side objects that should be sent as references to the client (but not themselves serialized in this + * payload) can be exported using the {@code exporter} - each returned {@link Exporter.Reference} will have an + * {@code index}, denoting its position on the array of exported objects to be received by the client. + * + * @param exporter the exporter + * @param object the compatible object + * @param out the output stream + * @throws IOException if output stream operations failed, the export will then fail, and the client will get a + * generic error + */ + public abstract void writeCompatibleObjectTo(Exporter exporter, Object object, OutputStream out) + throws IOException; + + @Override + public MessageStream compatibleClientConnection(Object object, MessageStream connection) + throws ObjectCommunicationException { + Exporter exporter = new Exporter(); + + try { + writeCompatibleObjectTo(exporter, object, exporter.outputStream()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + connection.onData(exporter.payload(), exporter.references()); + connection.onClose(); + return MessageStream.NOOP; + } + } } diff --git a/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeClassBase.java b/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeClassBase.java index fd390f99bb2..b61b6acb667 100644 --- a/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeClassBase.java +++ b/plugin/src/main/java/io/deephaven/plugin/type/ObjectTypeClassBase.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.util.Objects; /** @@ -21,8 +22,6 @@ public ObjectTypeClassBase(String name, Class clazz) { this.clazz = Objects.requireNonNull(clazz); } - public abstract void writeToImpl(Exporter exporter, T object, OutputStream out) throws IOException; - public final Class clazz() { return clazz; } @@ -38,13 +37,64 @@ public final boolean isType(Object object) { } @Override - public final void writeCompatibleObjectTo(Exporter exporter, Object object, OutputStream out) throws IOException { - // noinspection unchecked - writeToImpl(exporter, (T) object, out); + public final MessageStream compatibleClientConnection(Object object, MessageStream connection) + throws ObjectCommunicationException { + return clientConnectionImpl((T) object, connection); } + public abstract MessageStream clientConnectionImpl(T object, MessageStream connection) + throws ObjectCommunicationException; + @Override public String toString() { return name + ":" + clazz.getName(); } + + /** + * Abstract base class for object type plugins that can only be fetched (and will not have later responses or accept + * later requests). For bidirectional messages, see {@link ObjectTypeClassBase}. + * + * @param the class type + */ + public abstract static class FetchOnly extends ObjectTypeClassBase { + + public FetchOnly(String name, Class clazz) { + super(name, clazz); + } + + @Override + public final MessageStream clientConnectionImpl(T object, MessageStream connection) + throws ObjectCommunicationException { + Exporter exporter = new Exporter(); + + try { + writeToImpl(exporter, object, exporter.outputStream()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + connection.onData(exporter.payload(), exporter.references()); + connection.onClose(); + + return MessageStream.NOOP; + } + + /** + * Serializes {@code object} as bytes to {@code out}. Must only be called with {@link #isType(Object) a + * compatible object}. + * + * Server-side objects that should be sent as references to the client (but not themselves serialized in this + * payload) can be exported using the {@code exporter} - each returned {@link Exporter.Reference} will have an + * {@code index}, denoting its position on the array of exported objects to be received by the client. + * + * @param exporter the exporter + * @param object the compatible object + * @param out the output stream + * + * @throws IOException if output stream operations failed, the export will then fail, and the client will get a + * generic error + */ + public abstract void writeToImpl(Exporter exporter, T object, OutputStream out) throws IOException; + } + } diff --git a/proto/proto-backplane-grpc/src/main/proto/deephaven/proto/object.proto b/proto/proto-backplane-grpc/src/main/proto/deephaven/proto/object.proto index a98304c69c5..af361967665 100644 --- a/proto/proto-backplane-grpc/src/main/proto/deephaven/proto/object.proto +++ b/proto/proto-backplane-grpc/src/main/proto/deephaven/proto/object.proto @@ -12,7 +12,70 @@ option go_package = "github.com/deephaven/deephaven-core/go/internal/proto/objec import "deephaven/proto/ticket.proto"; service ObjectService { - rpc FetchObject(FetchObjectRequest) returns (FetchObjectResponse) {} + + /* + * Fetches a server-side object as a binary payload and assorted other tickets pointing at + * other server-side objects that may need to be read to properly use this payload. The binary + * format is implementation specific, but the implementation should be specified by the "type" + * identifier in the typed ticket. + * + * Deprecated in favor of MessageStream, which is able to handle the same content. + */ + rpc FetchObject(FetchObjectRequest) returns (FetchObjectResponse) { + option deprecated = true; + } + + /* + * Provides a generic stream feature for Deephaven instances to use to add arbitrary functionality. + * Presently these take the form of "object type plugins", where server-side code can specify how + * an object could be serialized and/or communicate with a client. This gRPC stream is somewhat lower level + * than the plugin API, giving the server and client APIs features to correctly establish and + * control the stream. At this time, this is limited to a "ConnectRequest" to start the call. + * + * The first message sent to the server is expected to have a ConnectRequest, indicating which + * export ticket to connect to. It is an error for the client to attempt to connect to an object + * that has no plugin for its object type installed. + * + * The first request sent by the client should be a ConnectRequest. No other client message should + * be sent until the server responds. The server will respond with Data as soon as it is able (i.e. + * once the object in question has been resolved and the plugin has responded), indicating that the + * request was successful. After that point, the client may send Data requests. + * + * All replies from the server to the client contain Data instances. When sent from the server to + * the client, Data contains a bytes payload created by the server implementation of the plugin, + * and server-created export tickets containing any object references specified to be sent by the + * server-side plugin. As server-created exports, they are already resolved, and can be fetched or + * otherwise referenced right away. The client API is expected to wrap those tickets in appropriate + * objects, and the client is expected to release those tickets as appropriate, according to the + * plugin's use case. Note that it is possible for the "type" field to be null, indicating that + * there is no corresponding ObjectType plugin for these exported objects. This limits the client + * to specifying those tickets in a subsequent request, or releasing the ticket to let the object + * be garbage collected on the server. + * + * All Data instances sent from the client likewise contain a bytes payload, and may contain + * references to objects that already exist or may soon exist on the server, not just tickets sent + * by this same plugin. Note however that if those tickets are not yet resolved, neither the current + * Data nor subsequent requests can be processed by the plugin, as the required references can't be + * resolved. + * + * Presently there is no explicit "close" message to send, but plugin implementations can devise + * their own "half-close" protocol if they so choose. For now, if one end closes the connection, + * the other is expected to follow suit by closing their end too. At present, if there is an error + * with the stream, it is conveyed to the client in the usual gRPC fashion, but the server plugin + * will only be informed that the stream closed. + * + */ + rpc MessageStream(stream StreamRequest) returns (stream StreamResponse) {} + + /* + * Half of the browser-based (browser's can't do bidirectional streams without websockets) + * implementation for MessageStream. + */ + rpc OpenMessageStream(StreamRequest) returns (stream StreamResponse) {} + /* + * Other half of the browser-based implementation for MessageStream. + */ + rpc NextMessageStream(StreamRequest) returns (BrowserNextResponse) {} } message FetchObjectRequest { @@ -22,5 +85,66 @@ message FetchObjectRequest { message FetchObjectResponse { string type = 1; bytes data = 2; - repeated io.deephaven.proto.backplane.grpc.TypedTicket typed_export_id = 3; + repeated io.deephaven.proto.backplane.grpc.TypedTicket typed_export_ids = 3; +} + +/* + * First payload to send on a MessageStream, indicating the object to connect to + * on the server. + */ +message ConnectRequest { + io.deephaven.proto.backplane.grpc.TypedTicket source_id = 1; +} + +/* + * A generic payload that can be sent by either the server or the client, containing + * arbitrary binary data, and any number of typed tickets. The current convention is + * that the client can send tickets it was given from the server, and the server will + * send server-created export tickets for new objects. + */ +message Data { + // Arbitrary bytes defined by the plugin's definition/purpose. + bytes payload = 1; + /* + * References to be sent client->server or server->client. + * + * When the server sends references to objects on the server, those objects already + * exist and can be exported right away. Those tickets then are server-sent exports, + * and are already resolved. Note that these references could be missing a type, + * meaning that the object cannot be fetched, but can still be released or passed + * back to the server. To correctly free up unused server resources, clients must + * take care to release tickets when they will no longer be used. + * + * Tickets sent from the client to the server can be any ticket, resolved or not. + * This lets the client reference objects that already exist on the server or are + * still pending. Note that pending tickets require the server to wait until that + * object exists before passing this Data request to the server plugin, and since + * messages are always processed in order, later requests will also be delayed. + */ + repeated io.deephaven.proto.backplane.grpc.TypedTicket exported_references = 2; +} + +/* + * Client payload for the MessageStream. + */ +message StreamRequest { + oneof message { + // Indicates that this is the first request of the stream, asking to connect to + // a specific object on the server. + ConnectRequest connect = 1; + // Data to pass to the object on the server. + Data data = 2; + } +} +/* + * Server responses to the client. Currently can only be Data messages. + */ +message StreamResponse { + oneof message { + // Data to pass to the client about the object on the server. + Data data = 1; + } +} + +message BrowserNextResponse { } diff --git a/py/client/build.gradle b/py/client/build.gradle index 589c006e8e2..e364f6a0823 100644 --- a/py/client/build.gradle +++ b/py/client/build.gradle @@ -92,6 +92,12 @@ def testPyClient = Docker.registerDockerTask(project, 'testPyClient') { from ('requirements-dev.txt') { into 'project/' } + from ('setup.py') { + into 'project/' + } + from ('README.md') { + into 'project/' + } } containerDependencies.dependsOn = [deephavenDocker.healthyTask] containerDependencies.finalizedBy = deephavenDocker.endTask @@ -104,6 +110,8 @@ def testPyClient = Docker.registerDockerTask(project, 'testPyClient') { mkdir -p /out/report; \\ pip3 install --upgrade pip; \\ pip3 install -r requirements-dev.txt''' + + runCommand 'pip install .' environmentVariable 'DH_HOST', deephavenDocker.containerName.get() environmentVariable 'DH_PORT', '10000' } diff --git a/py/client/pydeephaven/_arrow_flight_service.py b/py/client/pydeephaven/_arrow_flight_service.py index a409ab73b20..0f0834d081d 100644 --- a/py/client/pydeephaven/_arrow_flight_service.py +++ b/py/client/pydeephaven/_arrow_flight_service.py @@ -53,10 +53,10 @@ def do_exchange(self): """Starts an Arrow do_exchange operation. Returns: - The corresonding Arrow FlightStreamWriter and FlightStreamReader. + The corresponding Arrow FlightStreamWriter and FlightStreamReader. """ try: - desc = pa.flight.FlightDescriptor.for_command(b"dphn") + desc = pa.flight.FlightDescriptor.for_command(b"dphn") options = paflight.FlightCallOptions(headers=self.session.grpc_metadata) writer, reader = self._flight_client.do_exchange(desc, options) return writer, reader diff --git a/py/client/pydeephaven/_plugin_obj_service.py b/py/client/pydeephaven/_plugin_obj_service.py new file mode 100644 index 00000000000..3e5fa75db9f --- /dev/null +++ b/py/client/pydeephaven/_plugin_obj_service.py @@ -0,0 +1,29 @@ +# +# Copyright (c) 2016-2023 Deephaven Data Labs and Patent Pending +# +import io +from typing import Any + +from pydeephaven.dherror import DHError +from pydeephaven.proto import object_pb2_grpc +from pydeephaven.experimental.plugin_client import PluginRequestStream + + +"""This module provides internal tools to communicate with plugins on the server.""" + + +class PluginObjService: + """ + PluginObjectService defines utility methods to make gRPC calls to the ObjectService. + """ + def __init__(self, session: 'pydeephaven.session.Session'): + self.session = session + self._grpc_app_stub = object_pb2_grpc.ObjectServiceStub(session.grpc_channel) + + def message_stream(self, req_stream: PluginRequestStream) -> Any: + """Opens a connection to the server-side implementation of this plugin.""" + try: + resp = self._grpc_app_stub.MessageStream(req_stream, metadata=self.session.grpc_metadata) + return resp + except Exception as e: + raise DHError("failed to establish bidirectional stream with the server.") from e diff --git a/py/client/pydeephaven/_table_service.py b/py/client/pydeephaven/_table_service.py index 7e71c54d69d..f6c98422d09 100644 --- a/py/client/pydeephaven/_table_service.py +++ b/py/client/pydeephaven/_table_service.py @@ -58,3 +58,14 @@ def grpc_table_op(self, table: Table, op: TableOp, table_class: type = Table) -> raise DHError(f"Server error received for {op.__class__.__name__}: {response.error_info}") except Exception as e: raise DHError(f"failed to finish {op.__class__.__name__} operation") from e + + def fetch_etcr(self, ticket) -> Table: + """Given a ticket, constructs a table around it, by fetching metadata from the server.""" + response = self._grpc_table_stub.GetExportedTableCreationResponse(ticket, metadata=self.session.grpc_metadata) + if response.success: + return Table(self.session, ticket=response.result_id.ticket, + schema_header=response.schema_header, + size=response.size, + is_static=response.is_static) + else: + raise DHError(f"Server error received for ExportedTableCreationResponse: {response.error_info}") diff --git a/py/client/pydeephaven/experimental/__init__.py b/py/client/pydeephaven/experimental/__init__.py new file mode 100644 index 00000000000..90897369d67 --- /dev/null +++ b/py/client/pydeephaven/experimental/__init__.py @@ -0,0 +1,7 @@ +# +# Copyright (c) 2016-2023 Deephaven Data Labs and Patent Pending +# + +""" +Experimental APIs for client-side plugins. +""" \ No newline at end of file diff --git a/py/client/pydeephaven/experimental/plugin_client.py b/py/client/pydeephaven/experimental/plugin_client.py new file mode 100644 index 00000000000..96a04e32f59 --- /dev/null +++ b/py/client/pydeephaven/experimental/plugin_client.py @@ -0,0 +1,131 @@ +# +# Copyright (c) 2016-2023 Deephaven Data Labs and Patent Pending +# + +""" +Experimental module to communicate with server-side plugins from the client. +""" +import threading +from queue import SimpleQueue +from typing import Any, List, Union + +from pydeephaven.proto import object_pb2 +from pydeephaven.proto import ticket_pb2 +from .server_object import ServerObject +from pydeephaven.dherror import DHError +from pydeephaven.table import Table + + +class PluginClient(ServerObject): + """ + Connected to an object on the server, this provides access to that object through messages sent from the server. + Use resp_stream to read messages that the server has sent, and req_stream to send messages back to the server, if + supported. + """ + + def __init__(self, session: 'pydeephaven.session.Session', exportable_obj: ticket_pb2.Ticket): + super().__init__(type_=exportable_obj.type, ticket=exportable_obj.ticket) + self.session = session + self.exportable_obj = exportable_obj + self.req_stream = PluginRequestStream(SimpleQueue(), self.exportable_obj) + self.resp_stream = PluginResponseStream(self._open(), self.session) + + def _open(self) -> Any: + return self.session.plugin_object_service.message_stream(self.req_stream) + + def close(self) -> None: + self.req_stream.close() + self.resp_stream.close() + + +class Fetchable(ServerObject): + """ + Represents an object on the server that could be fetched and used or communicated with from the client. + """ + + def __init__(self, session, typed_ticket: ticket_pb2.TypedTicket): + super().__init__(type_=typed_ticket.type, ticket=typed_ticket.ticket) + self.session = session + self.typed_ticket = typed_ticket + + def fetch(self) -> Union[Table, PluginClient]: + """ + Returns a client object that can be interacted with, representing an object that actually only exists on the + server. In contrast to a Fetchable instance, which only serves as a reference to a server object, + this method can return a Table or PluginClient. Note that closing this Fetchable or the result returned from + this method will also close the other, take care when signaling that it is safe to release this object on + the server. + """ + if self.typed_ticket.type is None: + raise DHError("Cannot fetch an object with no type, the server has no ObjectType plugin registered to " + "support it.") + if self.typed_ticket.type == 'Table': + return self.session.table_service.fetch_etcr(self.typed_ticket.ticket) + return PluginClient(self.session, self.typed_ticket) + + def close(self) -> None: + self.session.release(self.typed_ticket) + + +class PluginRequestStream: + """ + A stream of requests to the server. If supported by the server-side plugin, these will be processed on the server + in the order they are sent. + """ + + def __init__(self, req_queue: SimpleQueue, source_ticket): + self.req_queue = req_queue + connect_req = object_pb2.ConnectRequest(source_id=source_ticket) + stream_req = object_pb2.StreamRequest(connect=connect_req) + self.req_queue.put(stream_req) + self._sentinel = object() + + def write(self, payload: bytes, references: List[ServerObject]) -> None: + """ + Sends a message to the server, consisting of a payload of bytes and a list of objects that exist on the server. + """ + data_message = object_pb2.Data(payload=payload, exported_references=[obj.typed_ticket() for obj in references]) + stream_req = object_pb2.StreamRequest(data=data_message) + self.req_queue.put(stream_req) + + def __next__(self): + if (req := self.req_queue.get()) != self._sentinel: + return req + else: + raise StopIteration + + def __iter__(self): + return self + + def close(self) -> None: + self.req_queue.put(self._sentinel) + + +class PluginResponseStream: + """ + A stream of responses from the server. Will contain at least one response from when the object was first connected + to, depending on the server implementation. + """ + + def __init__(self, stream_resp, session: 'pydeephaven.session.Session'): + self.stream_resp = stream_resp + self.session = session + self._rlock = threading.RLock() + + def __next__(self): + with self._rlock: + if not self.stream_resp: + raise RuntimeError("the response stream is closed.") + try: + resp = next(self.stream_resp) + except StopIteration as e: + raise + else: + return resp.data.payload, [Fetchable(self.session, ticket) for ticket in resp.data.exported_references] + + def __iter__(self): + return self + + def close(self) -> None: + with self._rlock: + self.stream_resp = None diff --git a/py/client/pydeephaven/experimental/server_object.py b/py/client/pydeephaven/experimental/server_object.py new file mode 100644 index 00000000000..4c151113e2b --- /dev/null +++ b/py/client/pydeephaven/experimental/server_object.py @@ -0,0 +1,35 @@ +# +# Copyright (c) 2016-2023 Deephaven Data Labs and Patent Pending +# + +import dataclasses +from pydeephaven.proto import ticket_pb2 +from typing import Optional + + +""" +A simple supertype to use when defining objects that exist on the server which can be referenced by the client. +""" + + +@dataclasses.dataclass +class ServerObject: + """ + Implementations of this type are client-side representations of objects that actually exist on the Deephaven server. + Presently used to enable the client API users to send and receive references to server-side plugins. + + Marked as "experimental" for now, as we work to improve the client plugin experience. + """ + + type_: Optional[str] + """The type of the object. May be None, indicating that the instance cannot be connected to or otherwise directly + used from the client.""" + + ticket: ticket_pb2.Ticket + """The ticket that points to the object on the server.""" + + def typed_ticket(self) -> ticket_pb2.TypedTicket: + """ + Returns a typed ticket, suitable for use in communicating with an ObjectType plugin on the server. + """ + return ticket_pb2.TypedTicket(type=self.type_, ticket=self.ticket) diff --git a/py/client/pydeephaven/proto/object_pb2.py b/py/client/pydeephaven/proto/object_pb2.py index 03970207a77..b62c5b5bf17 100644 --- a/py/client/pydeephaven/proto/object_pb2.py +++ b/py/client/pydeephaven/proto/object_pb2.py @@ -14,7 +14,7 @@ from pydeephaven.proto import ticket_pb2 as deephaven_dot_proto_dot_ticket__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x64\x65\x65phaven/proto/object.proto\x12!io.deephaven.proto.backplane.grpc\x1a\x1c\x64\x65\x65phaven/proto/ticket.proto\"W\n\x12\x46\x65tchObjectRequest\x12\x41\n\tsource_id\x18\x01 \x01(\x0b\x32..io.deephaven.proto.backplane.grpc.TypedTicket\"z\n\x13\x46\x65tchObjectResponse\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12G\n\x0ftyped_export_id\x18\x03 \x03(\x0b\x32..io.deephaven.proto.backplane.grpc.TypedTicket2\x8f\x01\n\rObjectService\x12~\n\x0b\x46\x65tchObject\x12\x35.io.deephaven.proto.backplane.grpc.FetchObjectRequest\x1a\x36.io.deephaven.proto.backplane.grpc.FetchObjectResponse\"\x00\x42\x42H\x01P\x01Z Dict[str, ticket_pb2.TypedTicket]: + with self._r_lock: + fields = self._fetch_fields() + return {field.field_name: field.typed_ticket for field in fields if field.application_id == 'scope'} + @property def grpc_metadata(self): l = [(b'authorization', self._auth_token)] @@ -249,6 +258,13 @@ def input_table_service(self) -> InputTableService: return self._input_table_service + @property + def plugin_object_service(self) -> PluginObjService: + if not self._plugin_obj_service: + self._plugin_obj_service = PluginObjService(self) + + return self._plugin_obj_service + def make_ticket(self, ticket_no=None): if not ticket_no: ticket_no = self.get_ticket() @@ -519,3 +535,12 @@ def input_table(self, schema: pa.Schema = None, init_table: Table = None, input_table = self.table_service.grpc_table_op(None, table_op, table_class=InputTable) input_table.key_cols = key_cols return input_table + + def plugin_client(self, exportable_obj: ticket_pb2.TypedTicket) -> PluginClient: + """Wraps a ticket as a PluginClient. Capabilities here vary based on the server implementation of the ObjectType, + but most will at least send a response payload to the client, possibly including references to other objects. + In some cases, depending on the server implementation, the client will also be able to send the same sort of + messages back to the server. + + Part of the experimental plugin API.""" + return PluginClient(self, exportable_obj) diff --git a/py/client/pydeephaven/table.py b/py/client/pydeephaven/table.py index eb8c410cb57..478616eece8 100644 --- a/py/client/pydeephaven/table.py +++ b/py/client/pydeephaven/table.py @@ -17,8 +17,10 @@ from pydeephaven._table_interface import TableInterface from pydeephaven.updateby import UpdateByOperation +from pydeephaven.experimental.server_object import ServerObject -class Table(TableInterface): + +class Table(TableInterface, ServerObject): """A Table object represents a reference to a table on the server. It is the core data structure of Deephaven and supports a rich set of operations such as filtering, sorting, aggregating, joining, snapshotting etc. @@ -34,6 +36,7 @@ def table_op_handler(self, table_op): return self.session.table_service.grpc_table_op(self, table_op) def __init__(self, session, ticket, schema_header=b'', size=None, is_static=None, schema=None): + ServerObject.__init__(self, type_="Table", ticket=ticket) if not session or not session.is_alive: raise DHError("Must be associated with a active session") self.session = session diff --git a/py/client/tests/test_multi_session.py b/py/client/tests/test_multi_session.py index 4e01f497491..366638b9126 100644 --- a/py/client/tests/test_multi_session.py +++ b/py/client/tests/test_multi_session.py @@ -3,11 +3,11 @@ # import unittest +import timeout_decorator + from pydeephaven import Session from tests.testbase import BaseTestCase -import timeout_decorator -import time class MultiSessionTestCase(BaseTestCase): def test_persistent_tables(self): diff --git a/py/client/tests/test_plugin_client.py b/py/client/tests/test_plugin_client.py new file mode 100644 index 00000000000..77fc17d86ce --- /dev/null +++ b/py/client/tests/test_plugin_client.py @@ -0,0 +1,37 @@ +# +# Copyright (c) 2016-2023 Deephaven Data Labs and Patent Pending +# +import unittest + +from tests.testbase import BaseTestCase + + +class PluginClientTestCase(BaseTestCase): + def setUp(self) -> None: + super().setUp() + server_script = ''' +from deephaven.plot.figure import Figure +from deephaven import empty_table + +source = empty_table(20).update(["Letter = (i % 2 == 0) ? `A` : `B`", "X = 0.1 * i", "Y = randomDouble(0.0, 5.0)"]) + +plot = Figure().plot_xy(series_name="Random numbers", t=source, x="X", y="Y").show() + +source2 = empty_table(20).update(["Letter = (i % 2 == 0) ? `A` : `B`", "X = 0.1 * i", "Y = randomDouble(0.0, 5.0)"]) + +plot2 = Figure().plot_xy(series_name="Random numbers", t=source2, x="X", y="Y", by=["Letter"]).show() + ''' + self.session.run_script(server_script) + + def test_create(self): + plugin_client = self.session.plugin_client(self.session.exportable_objects["plot"]) + self.assertIsNotNone(plugin_client) + payload, refs = next(plugin_client.resp_stream) + self.assertGreater(len(payload), 0) + self.assertGreater(len(refs), 0) + ref = refs[0] + self.assertEqual(ref.type_, "Table") + + +if __name__ == "__main__": + unittest.main() diff --git a/py/server/deephaven/pandasplugin/__init__.py b/py/server/deephaven/pandasplugin/__init__.py index 726659d955f..b28a6255b29 100644 --- a/py/server/deephaven/pandasplugin/__init__.py +++ b/py/server/deephaven/pandasplugin/__init__.py @@ -2,10 +2,11 @@ # Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending # -from deephaven.plugin import Registration +from deephaven.plugin import Registration, Callback from . import pandas_as_table + class PandasPluginRegistration(Registration): @classmethod - def register_into(clscls, callback: Registration.Callback) -> None: + def register_into(clscls, callback: Callback) -> None: callback.register(pandas_as_table.PandasDataFrameSerializer) diff --git a/py/server/deephaven/pandasplugin/pandas_as_table.py b/py/server/deephaven/pandasplugin/pandas_as_table.py index c4432d42c99..a6b2ddc1dc4 100644 --- a/py/server/deephaven/pandasplugin/pandas_as_table.py +++ b/py/server/deephaven/pandasplugin/pandas_as_table.py @@ -3,13 +3,13 @@ # from deephaven.pandas import to_table -from deephaven.plugin.object import Exporter, ObjectType +from deephaven.plugin.object_type import Exporter, FetchOnlyObjectType from pandas import DataFrame NAME = "pandas.DataFrame" -class PandasDataFrameSerializer(ObjectType): +class PandasDataFrameSerializer(FetchOnlyObjectType): @property def name(self) -> str: return NAME diff --git a/py/server/deephaven/server/plugin/object/__init__.py b/py/server/deephaven/server/plugin/object/__init__.py deleted file mode 100644 index ca9367cd77e..00000000000 --- a/py/server/deephaven/server/plugin/object/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending -# - -import jpy - -from typing import Optional -from deephaven.plugin.object import Exporter, ObjectType, Reference -from deephaven._wrapper import JObjectWrapper - -_JReference = jpy.get_type('io.deephaven.plugin.type.ObjectType$Exporter$Reference') -_JExporterAdapter = jpy.get_type('io.deephaven.server.plugin.python.ExporterAdapter') - - -def _adapt_reference(ref: _JReference) -> Reference: - return Reference(ref.index(), ref.type().orElse(None)) - - -def _unwrap(object): - # todo: we should have generic unwrapping code ABC - if isinstance(object, JObjectWrapper): - return object.j_object - return object - - -class ExporterAdapter(Exporter): - def __init__(self, exporter: _JExporterAdapter): - self._exporter = exporter - - def reference(self, object, allow_unknown_type : bool = False, force_new : bool = False) -> Optional[Reference]: - object = _unwrap(object) - if isinstance(object, jpy.JType): - ref = self._exporter.reference(object, allow_unknown_type, force_new) - else: - ref = self._exporter.referencePyObject(object, allow_unknown_type, force_new) - return _adapt_reference(ref) if ref else None - - def __str__(self): - return str(self._exporter) - - -# see io.deephaven.server.plugin.python.ObjectTypeAdapter for calling details -class ObjectTypeAdapter: - def __init__(self, user_object_type: ObjectType): - self._user_object_type = user_object_type - - def is_type(self, object): - return self._user_object_type.is_type(object) - - def to_bytes(self, exporter: _JExporterAdapter, object): - return self._user_object_type.to_bytes(ExporterAdapter(exporter), object) - - def __str__(self): - return str(self._user_object_type) diff --git a/py/server/deephaven/server/plugin/__init__.py b/py/server/deephaven_internal/plugin/__init__.py similarity index 73% rename from py/server/deephaven/server/plugin/__init__.py rename to py/server/deephaven_internal/plugin/__init__.py index 818de49075c..bffb501b30e 100644 --- a/py/server/deephaven/server/plugin/__init__.py +++ b/py/server/deephaven_internal/plugin/__init__.py @@ -4,9 +4,9 @@ import jpy -_JCallbackAdapter = jpy.get_type('io.deephaven.server.plugin.python.CallbackAdapter') +JCallbackAdapter = jpy.get_type('io.deephaven.server.plugin.python.CallbackAdapter') -def initialize_all_and_register_into(callback: _JCallbackAdapter): +def initialize_all_and_register_into(callback: JCallbackAdapter): try: from . import register except ModuleNotFoundError as e: diff --git a/py/server/deephaven_internal/plugin/object/__init__.py b/py/server/deephaven_internal/plugin/object/__init__.py new file mode 100644 index 00000000000..93f578d9932 --- /dev/null +++ b/py/server/deephaven_internal/plugin/object/__init__.py @@ -0,0 +1,91 @@ +# +# Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending +# + +import jpy + +from typing import Optional, List, Any +from deephaven.plugin.object_type import Exporter, ObjectType, Reference, MessageStream, FetchOnlyObjectType +from deephaven._wrapper import JObjectWrapper, wrap_j_object + +JReference = jpy.get_type('io.deephaven.plugin.type.Exporter$Reference') +JExporterAdapter = jpy.get_type('io.deephaven.server.plugin.python.ExporterAdapter') +JMessageStream = jpy.get_type('io.deephaven.plugin.type.ObjectType$MessageStream') + + +def _adapt_reference(ref: JReference) -> Reference: + return Reference(ref.index(), ref.type().orElse(None)) + + +def _unwrap(object): + # todo: we should have generic unwrapping code ABC + if isinstance(object, JObjectWrapper): + return object.j_object + return object + + +class ExporterAdapter(Exporter): + """Python implementation of Exporter that delegates to its Java counterpart.""" + + def __init__(self, exporter: JExporterAdapter): + self._exporter = exporter + + def reference(self, obj: Any, allow_unknown_type: bool = True, force_new: bool = True) -> Optional[Reference]: + obj = _unwrap(obj) + if isinstance(obj, jpy.JType): + ref = self._exporter.reference(obj, allow_unknown_type, force_new) + else: + ref = self._exporter.referencePyObject(obj, allow_unknown_type, force_new) + return _adapt_reference(ref) if ref else None + + def __str__(self): + return str(self._exporter) + + +class ClientResponseStreamAdapter(MessageStream): + """Python implementation of MessageStream that delegates to its Java counterpart""" + def __init__(self, wrapped: JMessageStream): + self._wrapped = wrapped + + def on_data(self, payload: bytes, references: List[Any]) -> None: + self._wrapped.onData(payload, [_unwrap(ref) for ref in references]) + + def on_close(self) -> None: + self._wrapped.onClose() + + +class ServerRequestStreamAdapter(MessageStream): + """Wraps Python server MessageStream implementations to correctly adapt objects coming from the client + """ + def __init__(self, wrapped: MessageStream): + self._wrapped = wrapped + + def on_data(self, payload:bytes, references: List[Any]) -> None: + self._wrapped.on_data(payload, [wrap_j_object(ref) for ref in references]) + + def on_close(self) -> None: + self._wrapped.on_close() + + +class ObjectTypeAdapter: + """Python type that Java's ObjectTypeAdapter will call in order to communicate with a Python ObjectType instance.""" + + def __init__(self, user_object_type: ObjectType): + self._user_object_type = user_object_type + + def is_type(self, obj) -> bool: + return self._user_object_type.is_type(obj) + + def is_fetch_only(self) -> bool: + return isinstance(self._user_object_type, FetchOnlyObjectType) + + def to_bytes(self, exporter: JExporterAdapter, obj: Any) -> bytes: + return self._user_object_type.to_bytes(ExporterAdapter(exporter), obj) + + def create_client_connection(self, obj: Any, connection: JMessageStream) -> MessageStream: + return ServerRequestStreamAdapter( + self._user_object_type.create_client_connection(obj, ClientResponseStreamAdapter(connection)) + ) + + def __str__(self): + return str(self._user_object_type) diff --git a/py/server/deephaven/server/plugin/register.py b/py/server/deephaven_internal/plugin/register.py similarity index 75% rename from py/server/deephaven/server/plugin/register.py rename to py/server/deephaven_internal/plugin/register.py index ef61cd2d861..a35d152c91c 100644 --- a/py/server/deephaven/server/plugin/register.py +++ b/py/server/deephaven_internal/plugin/register.py @@ -6,18 +6,20 @@ import deephaven.plugin from typing import Union, Type -from deephaven.plugin import Plugin, Registration -from deephaven.plugin.object import ObjectType +from deephaven.plugin import Plugin, Registration, Callback +from deephaven.plugin.object_type import ObjectType from .object import ObjectTypeAdapter _JCallbackAdapter = jpy.get_type('io.deephaven.server.plugin.python.CallbackAdapter') def initialize_all_and_register_into(callback: _JCallbackAdapter): + """Python method that Java can call to create plugin instances on startup.""" deephaven.plugin.register_all_into(RegistrationAdapter(callback)) -class RegistrationAdapter(Registration.Callback): +class RegistrationAdapter(Callback): + """Python implementation of Callback that delegates to its Java counterpart.""" def __init__(self, callback: _JCallbackAdapter): self._callback = callback diff --git a/py/server/deephaven/server/script_session/__init__.py b/py/server/deephaven_internal/script_session/__init__.py similarity index 100% rename from py/server/deephaven/server/script_session/__init__.py rename to py/server/deephaven_internal/script_session/__init__.py diff --git a/py/server/setup.py b/py/server/setup.py index b37b9f5f2e4..847895ff4b1 100644 --- a/py/server/setup.py +++ b/py/server/setup.py @@ -54,7 +54,7 @@ def normalize_version(version): python_requires='>=3.8', install_requires=[ 'jpy>=0.14.0', - 'deephaven-plugin', + 'deephaven-plugin==0.5.0', 'numpy', 'pandas>=1.5.0', 'pyarrow', diff --git a/server/src/main/java/io/deephaven/server/object/ObjectServiceGrpcImpl.java b/server/src/main/java/io/deephaven/server/object/ObjectServiceGrpcImpl.java index 4ebfdd47949..ec5ea4fa947 100644 --- a/server/src/main/java/io/deephaven/server/object/ObjectServiceGrpcImpl.java +++ b/server/src/main/java/io/deephaven/server/object/ObjectServiceGrpcImpl.java @@ -3,51 +3,255 @@ */ package io.deephaven.server.object; -import com.google.protobuf.ByteStringAccess; +import com.google.protobuf.ByteString; import com.google.rpc.Code; -import io.deephaven.extensions.barrage.util.BarrageProtoUtil.ExposedByteArrayOutputStream; -import io.deephaven.internal.log.LoggerFactory; -import io.deephaven.io.logger.Logger; +import io.deephaven.base.verify.Assert; +import io.deephaven.engine.liveness.SingletonLivenessManager; +import io.deephaven.extensions.barrage.util.GrpcUtil; +import io.deephaven.plugin.type.ObjectCommunicationException; import io.deephaven.plugin.type.ObjectType; -import io.deephaven.plugin.type.ObjectType.Exporter; -import io.deephaven.plugin.type.ObjectType.Exporter.Reference; import io.deephaven.plugin.type.ObjectTypeLookup; -import io.deephaven.proto.backplane.grpc.FetchObjectRequest; -import io.deephaven.proto.backplane.grpc.FetchObjectResponse; -import io.deephaven.proto.backplane.grpc.FetchObjectResponse.Builder; -import io.deephaven.proto.backplane.grpc.ObjectServiceGrpc; -import io.deephaven.proto.backplane.grpc.TypedTicket; +import io.deephaven.proto.backplane.grpc.*; import io.deephaven.proto.util.Exceptions; +import io.deephaven.server.grpc.GrpcErrorHelper; import io.deephaven.server.session.SessionService; import io.deephaven.server.session.SessionState; import io.deephaven.server.session.SessionState.ExportObject; import io.deephaven.server.session.TicketRouter; +import io.deephaven.util.function.ThrowingRunnable; import io.grpc.stub.StreamObserver; import org.jetbrains.annotations.NotNull; import javax.inject.Inject; -import java.io.IOException; +import java.lang.Object; +import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.function.BiPredicate; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; public class ObjectServiceGrpcImpl extends ObjectServiceGrpc.ObjectServiceImplBase { - private static final Logger log = LoggerFactory.getLogger(ObjectServiceGrpcImpl.class); - private final SessionService sessionService; private final TicketRouter ticketRouter; private final ObjectTypeLookup objectTypeLookup; private final TypeLookup typeLookup; + private final SessionService.ErrorTransformer errorTransformer; + + @FunctionalInterface + interface StreamOperation extends ThrowingRunnable { + } @Inject public ObjectServiceGrpcImpl(SessionService sessionService, TicketRouter ticketRouter, - ObjectTypeLookup objectTypeLookup, TypeLookup typeLookup) { + ObjectTypeLookup objectTypeLookup, TypeLookup typeLookup, + SessionService.ErrorTransformer errorTransformer) { this.sessionService = Objects.requireNonNull(sessionService); this.ticketRouter = Objects.requireNonNull(ticketRouter); this.objectTypeLookup = Objects.requireNonNull(objectTypeLookup); this.typeLookup = Objects.requireNonNull(typeLookup); + this.errorTransformer = Objects.requireNonNull(errorTransformer); + } + + private enum EnqueuedState { + WAITING, RUNNING, CLOSED; + } + private final class SendMessageObserver extends SingletonLivenessManager implements StreamObserver { + private ExportObject object; + private final SessionState session; + private final StreamObserver responseObserver; + + private ObjectType.MessageStream messageStream; + + private final Queue operations = new ConcurrentLinkedQueue<>(); + private final AtomicReference runState = new AtomicReference<>(EnqueuedState.WAITING); + + class EnqueuedStreamOperation { + private final StreamOperation wrapped; + private final List> requirements; + + EnqueuedStreamOperation(ExportObject object, Collection> dependencies, + StreamOperation wrapped) { + this.wrapped = wrapped; + this.requirements = new ArrayList<>(dependencies); + this.requirements.add(object); + } + + public void run() { + session.nonExport() + .onErrorHandler(SendMessageObserver.this::onError) + .require(requirements) + .submit(() -> { + if (runState.get() == EnqueuedState.CLOSED) { + return; + } + // Run the specified work. Note that we're not concerned about exceptions, the stream will + // be dead (via onError) and won't be used again. + try { + wrapped.run(); + } catch (ObjectCommunicationException e) { + throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, + "Error performing MessageStream operation"); + } + + // Set state to WAITING if it is RUNNING so that any new work can race being added + if (runState.compareAndSet(EnqueuedState.RUNNING, EnqueuedState.WAITING)) { + doWork(); + } // else the stream should be ended and no more work done + }); + } + } + + private SendMessageObserver(SessionState session, StreamObserver responseObserver) { + this.session = session; + this.responseObserver = responseObserver; + } + + @Override + public void onNext(final StreamRequest request) { + GrpcErrorHelper.checkHasOneOf(request, "message"); + if (request.hasConnect()) { + if (this.object != null) { + throw Exceptions.statusRuntimeException(Code.FAILED_PRECONDITION, + "Already sent a connect request, cannot send another"); + } + + TypedTicket typedTicket = request.getConnect().getSourceId(); + + final String type = typedTicket.getType(); + if (type.isEmpty()) { + throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, "No type supplied"); + } + if (typedTicket.getTicket().getTicket().isEmpty()) { + throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, "No ticket supplied"); + } + + final SessionState.ExportObject object = ticketRouter.resolve( + session, typedTicket.getTicket(), "sourceId"); + + this.object = object; + manage(this.object); + runOrEnqueue(() -> { + final Object o = object.get(); + final ObjectType objectType = getObjectTypeInstance(type, o); + + PluginMessageSender clientConnection = new PluginMessageSender(responseObserver, session); + messageStream = objectType.clientConnection(o, clientConnection); + }); + } else if (request.hasData()) { + if (object == null) { + throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, + "Data message sent before Connect message"); + } + Data data = request.getData(); + List> referenceObjects = data.getExportedReferencesList().stream() + .map(typedTicket -> ticketRouter.resolve(session, typedTicket.getTicket(), "ticket")) + .collect(Collectors.toList()); + runOrEnqueue(referenceObjects, () -> { + Object[] objs = referenceObjects.stream().map(ExportObject::get).toArray(); + messageStream.onData(data.getPayload().asReadOnlyByteBuffer(), objs); + }); + } + } + + /** + * Helper to serialize incoming ObjectType messages. These methods are intended to roughly behave like + * SerializingExecutor(directExecutor()) in that only one can be running at a time, and will be started on the + * current thread, with the distinction that submitted work will continue off-thread and will signal when it is + * finished. + * + * @param operation the lambda to execute when it is our turn to run + */ + + private void runOrEnqueue(StreamOperation operation) { + runOrEnqueue(Collections.emptyList(), operation); + } + + /** + * Helper to serialize incoming ObjectType messages. These methods are intended to roughly behave like + * SerializingExecutor(directExecutor()) in that only one can be running at a time, and will be started on the + * current thread, with the distinction that submitted work will continue off-thread and will signal when it is + * finished. + * + * @param dependencies other ExportObjects that must be resolve to perform the operation + * @param operation the lambda to execute when it is our turn to run + */ + private void runOrEnqueue(Collection> dependencies, StreamOperation operation) { + // gRPC guarantees we can't race enqueuing + operations.add(new EnqueuedStreamOperation(object, dependencies, operation)); + doWork(); + } + + private void doWork() { + // More than one thread (at most two) can arrive here at the same time, but only one will pass the + // compareAndSet + EnqueuedStreamOperation next = operations.peek(); + + // If we fail the null check, no work to do, leave state as WAITING (though if work was added right after + // peek(), that thread will make it into here and start). If we fail the state check, something else has + // already started work + if (next != null && runState.compareAndSet(EnqueuedState.WAITING, EnqueuedState.RUNNING)) { + // We successfully set state to running, and should remove the item we just peeked at + EnqueuedStreamOperation actualNext = operations.poll(); + Assert.eq(next, "next", actualNext, "actualNext"); + + // Run the new item + next.run(); + } + } + + @Override + public void onError(final Throwable t) { + // Avoid starting more work + runState.set(EnqueuedState.CLOSED); + + // Safely inform the client that an error happened + GrpcUtil.safelyError(responseObserver, errorTransformer.transform(t)); + + // If the objecttype connection was opened, close it and refuse later calls from it + if (messageStream != null) { + closeMessageStream(); + } + + // Don't attempt to run additional work + operations.clear(); + + // Release the object itself + release(); + } + + private void closeMessageStream() { + try { + messageStream.onClose(); + } catch (Exception ignored) { + // ignore errors from closing the plugin + } + } + + @Override + public void onCompleted() { + // Don't finalize until we've processed earlier messages + runOrEnqueue(() -> { + runState.set(EnqueuedState.CLOSED); + // Respond by closing the stream - note that closing here allows the server plugin to respond to earlier + // messages without error, but those responses will be ignored by the client. + GrpcUtil.safelyComplete(responseObserver); + + // Let the server plugin know that the remote end has closed + if (messageStream != null) { + closeMessageStream(); + } + + // Release the exported object that this stream is communicating with + release(); + }); + } } @Override @@ -69,15 +273,58 @@ public void fetchObject( .onError(responseObserver) .submit(() -> { final Object o = object.get(); - final FetchObjectResponse response = serialize(type, session, o); - responseObserver.onNext(response); - responseObserver.onCompleted(); + ObjectType objectTypeInstance = getObjectTypeInstance(type, o); + + AtomicReference singleResponse = new AtomicReference<>(); + AtomicBoolean isClosed = new AtomicBoolean(false); + StreamObserver wrappedResponseObserver = new StreamObserver<>() { + @Override + public void onNext(StreamResponse value) { + singleResponse.set(FetchObjectResponse.newBuilder() + .setType(type) + .setData(value.getData().getPayload()) + .addAllTypedExportIds(value.getData().getExportedReferencesList()) + .build()); + } + + @Override + public void onError(Throwable t) { + responseObserver.onError(t); + } + + @Override + public void onCompleted() { + isClosed.set(true); + } + }; + PluginMessageSender connection = new PluginMessageSender(wrappedResponseObserver, session); + objectTypeInstance.clientConnection(o, connection); + + FetchObjectResponse message = singleResponse.get(); + if (message == null) { + connection.onClose(); + throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, + "Plugin didn't send a response before returning from clientConnection()"); + } + if (!isClosed.get()) { + connection.onClose(); + throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, + "Plugin didn't close response, use MessageStream instead for this object"); + } + GrpcUtil.safelyComplete(responseObserver, message); + return null; }); } - private FetchObjectResponse serialize(String expectedType, SessionState state, Object object) throws IOException { - final ExposedByteArrayOutputStream out = new ExposedByteArrayOutputStream(); + @Override + public StreamObserver messageStream(StreamObserver responseObserver) { + SessionState session = sessionService.getCurrentSession(); + return new SendMessageObserver(session, responseObserver); + } + + @NotNull + private ObjectType getObjectTypeInstance(String expectedType, Object object) { // TODO(deephaven-core#1872): Optimize ObjectTypeLookup final Optional o = objectTypeLookup.findObjectType(object); if (o.isEmpty()) { @@ -89,98 +336,59 @@ private FetchObjectResponse serialize(String expectedType, SessionState state, O throw Exceptions.statusRuntimeException(Code.FAILED_PRECONDITION, String.format( "Unexpected ObjectType, expected type '%s', actual type '%s'", expectedType, objectType.name())); } - final ExportCollector exportCollector = new ExportCollector(state); - try { - objectType.writeTo(exportCollector, object, out); - final Builder builder = FetchObjectResponse.newBuilder() - .setType(objectType.name()) - .setData(ByteStringAccess.wrap(out.peekBuffer(), 0, out.size())); - for (ReferenceImpl ref : exportCollector.refs()) { - builder.addTypedExportId(ref.typedTicket()); - } - return builder.build(); - } catch (Throwable t) { - cleanup(exportCollector, t); - throw t; - } + return objectType; } - private static void cleanup(ExportCollector exportCollector, Throwable t) { - for (ReferenceImpl ref : exportCollector.refs()) { + private static void cleanup(Collection> exports, Throwable t) { + for (ExportObject export : exports) { try { - ref.export.release(); + export.release(); } catch (Throwable inner) { t.addSuppressed(inner); } } } - private static boolean referenceEquality(Object t, Object u) { - return t == u; - } - - final class ExportCollector implements Exporter { - + private final class PluginMessageSender implements ObjectType.MessageStream { + private final StreamObserver responseObserver; private final SessionState sessionState; - private final Thread thread; - private final List references; - public ExportCollector(SessionState sessionState) { - this.sessionState = Objects.requireNonNull(sessionState); - this.thread = Thread.currentThread(); - this.references = new ArrayList<>(); - } - - public List refs() { - return references; + public PluginMessageSender(StreamObserver responseObserver, SessionState sessionState) { + this.responseObserver = responseObserver; + this.sessionState = sessionState; } @Override - public Optional reference(Object object, boolean allowUnknownType, boolean forceNew) { - return reference(object, allowUnknownType, forceNew, ObjectServiceGrpcImpl::referenceEquality); - } + public void onData(ByteBuffer message, Object[] references) throws ObjectCommunicationException { + List> exports = new ArrayList<>(references.length); + try { + Data.Builder payload = Data.newBuilder().setPayload(ByteString.copyFrom(message)); - @Override - public Optional reference(Object object, boolean allowUnknownType, boolean forceNew, - BiPredicate equals) { - if (thread != Thread.currentThread()) { - throw new IllegalStateException("Should only create references on the calling thread"); - } - if (!forceNew) { - for (ReferenceImpl reference : references) { - if (equals.test(object, reference.export.get())) { - return Optional.of(reference); - } + for (Object reference : references) { + final String type = typeLookup.type(reference).orElse(null); + final ExportObject exportObject = sessionState.newServerSideExport(reference); + exports.add(exportObject); + TypedTicket typedTicket = ticketForExport(exportObject, type); + payload.addExportedReferences(typedTicket); } - } - return newReferenceImpl(object, allowUnknownType); - } + final StreamResponse.Builder responseBuilder = + StreamResponse.newBuilder().setData(payload); - private Optional newReferenceImpl(Object object, boolean allowUnknownType) { - final String type = typeLookup.type(object).orElse(null); - if (!allowUnknownType && type == null) { - return Optional.empty(); + // Explicitly running this unsafely, we want the exception to clean up, but we still need to synchronize + // as would normally be done in safelyOnNext + StreamResponse response = responseBuilder.build(); + synchronized (responseObserver) { + responseObserver.onNext(response); + } + } catch (Throwable t) { + // Release any exports we failed to send, and report this as a checked exception + cleanup(exports, t); + throw new ObjectCommunicationException(t); } - final ExportObject exportObject = sessionState.newServerSideExport(object); - final ReferenceImpl ref = new ReferenceImpl(references.size(), type, exportObject); - references.add(ref); - return Optional.of(ref); - } - } - - private static final class ReferenceImpl implements Reference { - private final int index; - private final String type; - private final ExportObject export; - - public ReferenceImpl(int index, String type, ExportObject export) { - this.index = index; - this.type = type; - this.export = Objects.requireNonNull(export); } - public TypedTicket typedTicket() { - final TypedTicket.Builder builder = TypedTicket.newBuilder().setTicket(export.getExportId()); + private TypedTicket ticketForExport(ExportObject exportObject, String type) { + TypedTicket.Builder builder = TypedTicket.newBuilder().setTicket(exportObject.getExportId()); if (type != null) { builder.setType(type); } @@ -188,13 +396,8 @@ public TypedTicket typedTicket() { } @Override - public int index() { - return index; - } - - @Override - public Optional type() { - return Optional.ofNullable(type); + public void onClose() { + GrpcUtil.safelyComplete(responseObserver); } } } diff --git a/server/src/main/java/io/deephaven/server/plugin/python/Deephaven2ServerPluginModule.java b/server/src/main/java/io/deephaven/server/plugin/python/Deephaven2ServerPluginModule.java index fdbf9c0aaf3..fdd523f997b 100644 --- a/server/src/main/java/io/deephaven/server/plugin/python/Deephaven2ServerPluginModule.java +++ b/server/src/main/java/io/deephaven/server/plugin/python/Deephaven2ServerPluginModule.java @@ -8,7 +8,7 @@ interface Deephaven2ServerPluginModule extends AutoCloseable { - String MODULE = "deephaven.server.plugin"; + String MODULE = "deephaven_internal.plugin"; static Deephaven2ServerPluginModule of() { final PyModule module = PyModule.importModule(MODULE); diff --git a/server/src/main/java/io/deephaven/server/plugin/python/ExporterAdapter.java b/server/src/main/java/io/deephaven/server/plugin/python/ExporterAdapter.java index 475f1f75872..01d25e34e8d 100644 --- a/server/src/main/java/io/deephaven/server/plugin/python/ExporterAdapter.java +++ b/server/src/main/java/io/deephaven/server/plugin/python/ExporterAdapter.java @@ -3,8 +3,8 @@ */ package io.deephaven.server.plugin.python; -import io.deephaven.plugin.type.ObjectType.Exporter; -import io.deephaven.plugin.type.ObjectType.Exporter.Reference; +import io.deephaven.plugin.type.Exporter; +import io.deephaven.plugin.type.Exporter.Reference; import org.jpy.PyObject; import java.util.Objects; @@ -17,6 +17,10 @@ public ExporterAdapter(Exporter exporter) { this.exporter = Objects.requireNonNull(exporter); } + public Reference reference(Object object) { + return exporter.reference(object, true, true).get(); + } + public Reference reference(Object object, boolean allowUnknownType, boolean forceNew) { return exporter.reference(object, allowUnknownType, forceNew).orElse(null); } diff --git a/server/src/main/java/io/deephaven/server/plugin/python/ObjectTypeAdapter.java b/server/src/main/java/io/deephaven/server/plugin/python/ObjectTypeAdapter.java index e31c3afd388..8082d63e822 100644 --- a/server/src/main/java/io/deephaven/server/plugin/python/ObjectTypeAdapter.java +++ b/server/src/main/java/io/deephaven/server/plugin/python/ObjectTypeAdapter.java @@ -3,11 +3,12 @@ */ package io.deephaven.server.plugin.python; +import io.deephaven.plugin.type.ObjectCommunicationException; import io.deephaven.plugin.type.ObjectTypeBase; +import io.deephaven.plugin.type.Exporter; import org.jpy.PyObject; -import java.io.IOException; -import java.io.OutputStream; +import java.nio.ByteBuffer; import java.util.Objects; final class ObjectTypeAdapter extends ObjectTypeBase implements AutoCloseable { @@ -34,11 +35,66 @@ public boolean isType(Object object) { } @Override - public void writeCompatibleObjectTo(Exporter exporter, Object object, OutputStream out) throws IOException { - final byte[] bytes = objectTypeAdapter.call(byte[].class, "to_bytes", - ExporterAdapter.class, new ExporterAdapter(exporter), - PyObject.class, (PyObject) object); - out.write(bytes); + public MessageStream compatibleClientConnection(Object object, MessageStream connection) + throws ObjectCommunicationException { + if (objectTypeAdapter.call("is_fetch_only").getBooleanValue()) { + // Fall back and attempt to use old api: + // Using this simple implementation, even though the python code won't write to this, but instead will + // return a byte array directly + Exporter exporter = new Exporter(); + + final byte[] bytes = objectTypeAdapter.call(byte[].class, "to_bytes", + ExporterAdapter.class, new ExporterAdapter(exporter), + PyObject.class, (PyObject) object); + + // Send the message and close the stream + connection.onData(ByteBuffer.wrap(bytes), exporter.references()); + connection.onClose(); + + return MessageStream.NOOP; + } else { + PyObject newConnection = + objectTypeAdapter.call(PyObject.class, "create_client_connection", PyObject.class, + (PyObject) object, PythonClientMessageStream.class, + new PythonClientMessageStream(connection)); + return new PythonServerMessageStream(newConnection); + } + } + + private static class PythonClientMessageStream { + private final MessageStream delegate; + + private PythonClientMessageStream(MessageStream delegate) { + this.delegate = delegate; + } + + public void onData(byte[] payload, Object... references) throws ObjectCommunicationException { + delegate.onData(ByteBuffer.wrap(payload), references); + } + + public void onClose() { + delegate.onClose(); + } + } + + private static class PythonServerMessageStream implements MessageStream { + private final PyObject instance; + + private PythonServerMessageStream(PyObject instance) { + this.instance = instance; + } + + @Override + public void onData(ByteBuffer payload, Object[] references) { + byte[] bytes = new byte[payload.limit()]; + payload.get(bytes); + instance.call(void.class, "on_data", byte[].class, bytes, Object[].class, references); + } + + @Override + public void onClose() { + instance.call("on_close"); + } } @Override diff --git a/server/src/main/java/io/deephaven/server/session/SessionState.java b/server/src/main/java/io/deephaven/server/session/SessionState.java index 5bb52089725..54639d6a6ab 100644 --- a/server/src/main/java/io/deephaven/server/session/SessionState.java +++ b/server/src/main/java/io/deephaven/server/session/SessionState.java @@ -1266,7 +1266,7 @@ public ExportBuilder requiresSerialQueue() { * @return this builder */ public ExportBuilder require(final ExportObject... dependencies) { - export.setDependencies(Arrays.asList(dependencies)); + export.setDependencies(List.of(dependencies)); return this; } @@ -1277,8 +1277,8 @@ public ExportBuilder require(final ExportObject... dependencies) { * @param dependencies the parent dependencies * @return this builder */ - public ExportBuilder require(final List> dependencies) { - export.setDependencies(Collections.unmodifiableList(dependencies)); + public ExportBuilder require(final List> dependencies) { + export.setDependencies(List.copyOf(dependencies)); return this; } diff --git a/server/src/test/java/io/deephaven/server/object/ObjectServiceTest.java b/server/src/test/java/io/deephaven/server/object/ObjectServiceTest.java index 0c70445a77a..3794bc6c02a 100644 --- a/server/src/test/java/io/deephaven/server/object/ObjectServiceTest.java +++ b/server/src/test/java/io/deephaven/server/object/ObjectServiceTest.java @@ -6,8 +6,9 @@ import com.google.auto.service.AutoService; import io.deephaven.engine.table.Table; import io.deephaven.engine.util.TableTools; +import io.deephaven.plugin.type.Exporter; import io.deephaven.plugin.type.ObjectType; -import io.deephaven.plugin.type.ObjectType.Exporter.Reference; +import io.deephaven.plugin.type.Exporter.Reference; import io.deephaven.plugin.type.ObjectTypeClassBase; import io.deephaven.proto.backplane.grpc.FetchObjectRequest; import io.deephaven.proto.backplane.grpc.FetchObjectResponse; @@ -27,7 +28,6 @@ import java.io.OutputStream; import java.util.Arrays; import java.util.Objects; -import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; @@ -83,11 +83,12 @@ private void fetchMyObject(Ticket ticket, String expectedSomeString, int expecte final FetchObjectResponse response = channel().objectBlocking().fetchObject(request); assertThat(response.getType()).isEqualTo(MY_OBJECT_TYPE_NAME); - assertThat(response.getTypedExportIdCount()).isEqualTo(4); - assertThat(response.getTypedExportId(0).getType()).isEqualTo("Table"); - assertThat(response.getTypedExportId(1).getType()).isEqualTo(MY_REF_OBJECT_TYPE_NAME); - assertThat(response.getTypedExportId(2).getType()).isEmpty(); - assertThat(response.getTypedExportId(3).getType()).isEqualTo(MY_REF_OBJECT_TYPE_NAME); + assertThat(response.getTypedExportIdsCount()).isEqualTo(5); + assertThat(response.getTypedExportIds(0).getType()).isEqualTo("Table"); + assertThat(response.getTypedExportIds(1).getType()).isEqualTo(MY_REF_OBJECT_TYPE_NAME); + assertThat(response.getTypedExportIds(2).getType()).isEmpty(); + assertThat(response.getTypedExportIds(3).getType()).isEqualTo("Table"); + assertThat(response.getTypedExportIds(4).getType()).isEqualTo(MY_REF_OBJECT_TYPE_NAME); final DataInputStream dis = new DataInputStream(response.getData().newInput()); @@ -97,8 +98,8 @@ private void fetchMyObject(Ticket ticket, String expectedSomeString, int expecte readRef(dis, 0); // the extras - readRef(dis, 0); // our extra ref to table - readRef(dis, 3); // our new extra ref + readRef(dis, 3); // our extra ref to table, now an additional export + readRef(dis, 4); // our new extra ref readString(dis, expectedSomeString); readInt(dis, expectedSomeInt); @@ -141,30 +142,27 @@ public static class MyUnregisteredObject { } @AutoService(ObjectType.class) - public static class MyObjectType extends ObjectTypeClassBase { + public static class MyObjectType extends ObjectTypeClassBase.FetchOnly { public MyObjectType() { super(MY_OBJECT_TYPE_NAME, MyObject.class); } @Override public void writeToImpl(Exporter exporter, MyObject object, OutputStream out) throws IOException { - final Reference tableRef = exporter.reference(object.someTable, false, false).orElseThrow(); - final Reference objRef = exporter.reference(object.someObj, false, false).orElseThrow(); - final Reference unknownRef = exporter.reference(object.someUnknown, true, false).orElseThrow(); + final Reference tableRef = exporter.reference(object.someTable); + final Reference objRef = exporter.reference(object.someObj); + final Reference unknownRef = exporter.reference(object.someUnknown); - final Reference extraTableRef = exporter.reference(object.someTable, false, false).orElseThrow(); - final Reference extraNewObjRef = exporter.reference(object.someObj, false, true).orElseThrow(); + final Reference extraTableRef = exporter.reference(object.someTable); + final Reference extraNewObjRef = exporter.reference(object.someObj); - final Optional dontAllowUnknown = exporter.reference(new Object(), false, false); - - assertThat(tableRef.type()).contains("Table"); - assertThat(objRef.type()).contains(MY_REF_OBJECT_TYPE_NAME); + assertThat(tableRef.type()).isEmpty(); + assertThat(objRef.type()).isEmpty(); assertThat(unknownRef.type()).isEmpty(); - assertThat(extraTableRef.type()).contains("Table"); - assertThat(extraNewObjRef.type()).contains(MY_REF_OBJECT_TYPE_NAME); - assertThat(dontAllowUnknown).isEmpty(); + assertThat(extraTableRef.type()).isEmpty(); + assertThat(extraNewObjRef.type()).isEmpty(); - assertThat(tableRef.index()).isEqualTo(extraTableRef.index()); + assertThat(tableRef.index()).isNotEqualTo(extraTableRef.index()); assertThat(objRef.index()).isNotEqualTo(extraNewObjRef.index()); final DataOutputStream doas = new DataOutputStream(out); @@ -188,7 +186,7 @@ private static void writeRef(DataOutput out, Reference reference) throws IOExcep } @AutoService(ObjectType.class) - public static class MyRefObjectType extends ObjectTypeClassBase { + public static class MyRefObjectType extends ObjectTypeClassBase.FetchOnly { public MyRefObjectType() { super(MY_REF_OBJECT_TYPE_NAME, MyRefObject.class); } diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/HasEventHandling.java b/web/client-api/src/main/java/io/deephaven/web/client/api/HasEventHandling.java index c6931434c28..29a0f174dff 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/HasEventHandling.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/HasEventHandling.java @@ -38,12 +38,12 @@ protected String logPrefix() { } /** - * Listen for events on this table. + * Listen for events on this object. * - * @param name - * @param callback + * @param name the name of the event to listen for + * @param callback a function to call when the event occurs * @return Returns a cleanup function. - * @param + * @param the type of the data that the event will provide */ @JsMethod public RemoverFn addEventListener(String name, EventFn callback) { diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/JsPartitionedTable.java b/web/client-api/src/main/java/io/deephaven/web/client/api/JsPartitionedTable.java index a3fc052bede..1183a306798 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/JsPartitionedTable.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/JsPartitionedTable.java @@ -9,6 +9,7 @@ import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.partitionedtable_pb.GetTableRequest; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.partitionedtable_pb.MergeRequest; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.partitionedtable_pb.PartitionedTableDescriptor; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; import io.deephaven.web.client.api.barrage.WebBarrageUtils; import io.deephaven.web.client.api.barrage.def.ColumnDefinition; import io.deephaven.web.client.api.lifecycle.HasLifecycle; @@ -34,7 +35,7 @@ * the server to get each Table. All tables will have the same structure. */ @JsType(namespace = "dh", name = "PartitionedTable") -public class JsPartitionedTable extends HasLifecycle { +public class JsPartitionedTable extends HasLifecycle implements ServerObject { /** * Indicates that a new key has been added to the array of keys, which can now be fetched with getTable. @@ -114,6 +115,11 @@ public Promise refetch() { }); } + @Override + public TypedTicket typedTicket() { + return widget.typedTicket(); + } + private Promise subscribeToKeys() { subscription = keys.subscribe( JsArray.asJsArray(keys.findColumns(descriptor.getKeyColumnNamesList().asArray(new String[0])))); diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/JsTable.java b/web/client-api/src/main/java/io/deephaven/web/client/api/JsTable.java index 6119fdb46ec..082619007f1 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/JsTable.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/JsTable.java @@ -89,15 +89,12 @@ import static io.deephaven.web.client.fu.LazyPromise.logError; /** - * TODO provide hooks into the event handlers so we can see if no one is listening any more and release the table - * handle/viewport. - * * Provides access to data in a table. Note that several methods present their response through Promises. This allows * the client to both avoid actually connecting to the server until necessary, and also will permit some changes not to * inform the UI right away that they have taken place. */ @TsName(namespace = "dh", name = "Table") -public class JsTable extends HasLifecycle implements HasTableBinding, JoinableTable { +public class JsTable extends HasLifecycle implements HasTableBinding, JoinableTable, ServerObject { @JsProperty(namespace = "dh.Table") /** * The table size has updated, so live scrollbars and the like can be updated accordingly. @@ -232,6 +229,14 @@ public Promise refetch() { return Promise.reject("Cannot reconnect a Table with refetch(), see deephaven-core#3604"); } + @Override + public TypedTicket typedTicket() { + TypedTicket typedTicket = new TypedTicket(); + typedTicket.setTicket(state().getHandle().makeTicket()); + typedTicket.setType(JsVariableType.TABLE); + return typedTicket; + } + @JsMethod public Promise batch(JsConsumer userCode) { boolean rootBatch = batchDepth++ == 0; @@ -1085,16 +1090,11 @@ public Promise rollup(@TsTypeRef(JsRollupConfig.class) Object confi workerConnection.hierarchicalTableServiceClient().rollup(request, workerConnection.metadata(), c::apply); }); - JsWidget widget = new JsWidget(workerConnection, c -> { - FetchObjectRequest partitionedTableRequest = new FetchObjectRequest(); - partitionedTableRequest.setSourceId(new TypedTicket()); - partitionedTableRequest.getSourceId().setType(JsVariableType.HIERARCHICALTABLE); - partitionedTableRequest.getSourceId().setTicket(rollupTicket); - workerConnection.objectServiceClient().fetchObject(partitionedTableRequest, - workerConnection.metadata(), (fail, success) -> { - c.handleResponse(fail, success, rollupTicket); - }); - }); + TypedTicket typedTicket = new TypedTicket(); + typedTicket.setType(JsVariableType.HIERARCHICALTABLE); + typedTicket.setTicket(rollupTicket); + + JsWidget widget = new JsWidget(workerConnection, typedTicket); return Promise.all(widget.refetch(), rollupPromise) .then(ignore -> Promise.resolve(new JsTreeTable(workerConnection, widget))); @@ -1131,16 +1131,11 @@ public Promise treeTable(@TsTypeRef(JsTreeTableConfig.class) Object c::apply); }); - JsWidget widget = new JsWidget(workerConnection, c -> { - FetchObjectRequest partitionedTableRequest = new FetchObjectRequest(); - partitionedTableRequest.setSourceId(new TypedTicket()); - partitionedTableRequest.getSourceId().setType(JsVariableType.HIERARCHICALTABLE); - partitionedTableRequest.getSourceId().setTicket(treeTicket); - workerConnection.objectServiceClient().fetchObject(partitionedTableRequest, - workerConnection.metadata(), (fail, success) -> { - c.handleResponse(fail, success, treeTicket); - }); - }); + TypedTicket typedTicket = new TypedTicket(); + typedTicket.setType(JsVariableType.HIERARCHICALTABLE); + typedTicket.setTicket(treeTicket); + + JsWidget widget = new JsWidget(workerConnection, typedTicket); return Promise.all(widget.refetch(), treePromise) .then(ignore -> Promise.resolve(new JsTreeTable(workerConnection, widget))); @@ -1420,17 +1415,11 @@ public Promise partitionBy(Object keys, @JsOptional Boolean c::apply); }); // construct the partitioned table around the ticket created above + TypedTicket typedTicket = new TypedTicket(); + typedTicket.setType(JsVariableType.PARTITIONEDTABLE); + typedTicket.setTicket(partitionedTableTicket); Promise fetchPromise = - new JsPartitionedTable(workerConnection, new JsWidget(workerConnection, c -> { - FetchObjectRequest partitionedTableRequest = new FetchObjectRequest(); - partitionedTableRequest.setSourceId(new TypedTicket()); - partitionedTableRequest.getSourceId().setType(JsVariableType.PARTITIONEDTABLE); - partitionedTableRequest.getSourceId().setTicket(partitionedTableTicket); - workerConnection.objectServiceClient().fetchObject(partitionedTableRequest, - workerConnection.metadata(), (fail, success) -> { - c.handleResponse(fail, success, partitionedTableTicket); - }); - })).refetch(); + new JsPartitionedTable(workerConnection, new JsWidget(workerConnection, typedTicket)).refetch(); // Ensure that the partition failure propagates first, but the result of the fetch will be returned - both // are running concurrently. diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/JsTotalsTable.java b/web/client-api/src/main/java/io/deephaven/web/client/api/JsTotalsTable.java index 84498f12744..cd626811702 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/JsTotalsTable.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/JsTotalsTable.java @@ -10,6 +10,8 @@ import elemental2.dom.CustomEvent; import elemental2.dom.Event; import elemental2.promise.Promise; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; +import io.deephaven.web.client.api.console.JsVariableType; import io.deephaven.web.client.api.filter.FilterCondition; import io.deephaven.web.client.state.ClientTableState; import io.deephaven.web.shared.fu.RemoverFn; @@ -38,7 +40,7 @@ */ @TsInterface @TsName(namespace = "dh", name = "TotalsTable") -public class JsTotalsTable implements JoinableTable { +public class JsTotalsTable implements JoinableTable, ServerObject { private final JsTable wrappedTable; private final String directive; private final JsArray groupBy; @@ -78,6 +80,14 @@ public ClientTableState state() { return wrappedTable.state(); } + @Override + public TypedTicket typedTicket() { + TypedTicket typedTicket = new TypedTicket(); + typedTicket.setTicket(state().getHandle().makeTicket()); + typedTicket.setType(JsVariableType.TABLE); + return typedTicket; + } + @JsProperty public JsTotalsTableConfig getTotalsTableConfig() { JsTotalsTableConfig parsed = JsTotalsTableConfig.parse(directive); diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/ServerObject.java b/web/client-api/src/main/java/io/deephaven/web/client/api/ServerObject.java new file mode 100644 index 00000000000..e6142df35c0 --- /dev/null +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/ServerObject.java @@ -0,0 +1,73 @@ +package io.deephaven.web.client.api; + +import com.vertispan.tsdefs.annotations.TsInterface; +import com.vertispan.tsdefs.annotations.TsUnion; +import com.vertispan.tsdefs.annotations.TsUnionMember; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; +import io.deephaven.web.client.api.tree.JsTreeTable; +import io.deephaven.web.client.api.widget.JsWidget; +import io.deephaven.web.client.api.widget.JsWidgetExportedObject; +import jsinterop.annotations.JsIgnore; +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsType; + +/** + * Indicates that this object is a local representation of an object that exists on the server. Similar to HasLifecycle, + * but not quite the same - whereas HasLifecycle is entirely internal and provides and provides hooks for reconnect + * logic, this exists to get a typed ticket reference to an object on the server, to pass that same ticket back to the + * server again. + */ +public interface ServerObject { + @JsIgnore + TypedTicket typedTicket(); + + /** + * Note that we don't explicitly use this as a union type, but sort of as a way to pretend that ServerObject is a + * sealed type with this generated set of subtypes. + */ + @JsType(name = "?", namespace = JsPackage.GLOBAL, isNative = true) + @TsUnion + interface Union { + @TsUnionMember + @JsOverlay + default JsTable asTable() { + return (JsTable) this; + } + + @TsUnionMember + @JsOverlay + default JsWidget asWidget() { + return (JsWidget) this; + } + + @TsUnionMember + @JsOverlay + default JsWidgetExportedObject asWidgetExportedObject() { + return (JsWidgetExportedObject) this; + } + + @TsUnionMember + @JsOverlay + default JsPartitionedTable asPartitionedTable() { + return (JsPartitionedTable) this; + } + + @TsUnionMember + @JsOverlay + default JsTotalsTable asTotalsTable() { + return (JsTotalsTable) this; + } + + @TsUnionMember + @JsOverlay + default JsTreeTable asTreeTable() { + return (JsTreeTable) this; + } + + @JsOverlay + default ServerObject asServerObject() { + return (ServerObject) this; + } + } +} diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java b/web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java index 6fe2d3a44b3..dfecd01bdae 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java @@ -46,7 +46,7 @@ import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb_service.ConsoleServiceClient; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.hierarchicaltable_pb_service.HierarchicalTableServiceClient; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.inputtable_pb_service.InputTableServiceClient; -import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectRequest; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb_service.ObjectServiceClient; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.partitionedtable_pb_service.PartitionedTableServiceClient; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb.ReleaseRequest; @@ -82,6 +82,7 @@ import io.deephaven.web.client.api.state.StateCache; import io.deephaven.web.client.api.tree.JsTreeTable; import io.deephaven.web.client.api.widget.JsWidget; +import io.deephaven.web.client.api.widget.JsWidgetExportedObject; import io.deephaven.web.client.api.widget.plot.JsFigure; import io.deephaven.web.client.fu.JsItr; import io.deephaven.web.client.fu.JsLog; @@ -862,7 +863,7 @@ public Promise whenServerReady(String operationName) { public Promise getPartitionedTable(JsVariableDefinition varDef) { return whenServerReady("get a partitioned table") - .then(server -> new JsPartitionedTable(this, new JsWidget(this, c -> fetchObject(varDef, c))) + .then(server -> new JsPartitionedTable(this, new JsWidget(this, createTypedTicket(varDef))) .refetch()); } @@ -880,22 +881,36 @@ public Promise getFigure(JsVariableDefinition varDef) { } return whenServerReady("get a figure") .then(server -> new JsFigure(this, - c -> fetchObject(varDef, (fail, success, ignore) -> c.apply(fail, success))).refetch()); - } - - private void fetchObject(JsVariableDefinition varDef, JsWidget.WidgetFetchCallback c) { - FetchObjectRequest request = new FetchObjectRequest(); + c -> { + getWidget(varDef).then(widget -> { + FetchObjectResponse legacyResponse = new FetchObjectResponse(); + legacyResponse.setData(widget.getDataAsU8()); + legacyResponse.setType(widget.getType()); + legacyResponse.setTypedExportIdsList(Arrays.stream(widget.getExportedObjects()) + .map(JsWidgetExportedObject::typedTicket).toArray(TypedTicket[]::new)); + c.apply(null, legacyResponse); + return null; + }, error -> { + c.apply(error, null); + return null; + }); + }).refetch()); + } + + private TypedTicket createTypedTicket(JsVariableDefinition varDef) { TypedTicket typedTicket = new TypedTicket(); typedTicket.setTicket(TableTicket.createTicket(varDef)); typedTicket.setType(varDef.getType()); - request.setSourceId(typedTicket); - objectServiceClient().fetchObject(request, metadata(), - (fail, success) -> c.handleResponse(fail, success, typedTicket.getTicket())); + return typedTicket; } public Promise getWidget(JsVariableDefinition varDef) { + return getWidget(createTypedTicket(varDef)); + } + + public Promise getWidget(TypedTicket typedTicket) { return whenServerReady("get a widget") - .then(response -> new JsWidget(this, c -> fetchObject(varDef, c)).refetch()); + .then(response -> new JsWidget(this, typedTicket).refetch()); } public void registerSimpleReconnectable(HasLifecycle figure) { diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/tree/JsTreeTable.java b/web/client-api/src/main/java/io/deephaven/web/client/api/tree/JsTreeTable.java index 263b23f2683..18ae065378f 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/tree/JsTreeTable.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/tree/JsTreeTable.java @@ -34,6 +34,7 @@ import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.hierarchicaltable_pb.HierarchicalTableViewRequest; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.Condition; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.Ticket; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; import io.deephaven.web.client.api.*; import io.deephaven.web.client.api.barrage.WebBarrageUtils; import io.deephaven.web.client.api.barrage.def.ColumnDefinition; @@ -105,7 +106,7 @@ * property reflecting that the type of cells where hasChildren is false will be different from usual. */ @JsType(namespace = "dh", name = "TreeTable") -public class JsTreeTable extends HasLifecycle { +public class JsTreeTable extends HasLifecycle implements ServerObject { /** * event.detail is the currently visible viewport data based on the active viewport configuration. */ @@ -1026,6 +1027,11 @@ public void close() { } } + @Override + public TypedTicket typedTicket() { + return widget.typedTicket(); + } + /** * Applies the given sort to all levels of the tree. Returns the previous sort in use. * diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidget.java b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidget.java index 898996b718e..1ce61f75ade 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidget.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidget.java @@ -3,83 +3,290 @@ */ package io.deephaven.web.client.api.widget; -import com.vertispan.tsdefs.annotations.TsInterface; import com.vertispan.tsdefs.annotations.TsName; +import com.vertispan.tsdefs.annotations.TsTypeRef; +import com.vertispan.tsdefs.annotations.TsUnion; +import com.vertispan.tsdefs.annotations.TsUnionMember; +import elemental2.core.ArrayBuffer; +import elemental2.core.ArrayBufferView; +import elemental2.core.JsArray; import elemental2.core.Uint8Array; +import elemental2.dom.CustomEventInit; import elemental2.promise.Promise; -import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.*; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.Ticket; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; +import io.deephaven.web.client.api.HasEventHandling; +import io.deephaven.web.client.api.ServerObject; import io.deephaven.web.client.api.WorkerConnection; -import jsinterop.annotations.JsFunction; +import io.deephaven.web.client.api.barrage.stream.BiDiStream; import jsinterop.annotations.JsMethod; +import jsinterop.annotations.JsOptional; +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; +import jsinterop.base.Js; -@TsInterface +import java.nio.charset.StandardCharsets; +import java.util.function.Supplier; + +/** + * A Widget represents a server side object that sends one or more responses to the client. The client can then + * interpret these responses to see what to render, or how to respond. + * + * Most custom object types result in a single response being sent to the client, often with other exported objects, but + * some will have streamed responses, and allow the client to send follow-up requests of its own. This class's API is + * backwards compatible, but as such does not offer a way to tell the difference between a streaming or non-streaming + * object type, the client code that handles the payloads is expected to know what to expect. See + * dh.WidgetMessageDetails for more information. + * + * When the promise that returns this object resolves, it will have the first response assigned to its fields. Later + * responses from the server will be emitted as "message" events. When the connection with the server ends + */ +// TODO consider reconnect support? This is somewhat tricky without understanding the semantics of the widget @TsName(namespace = "dh", name = "Widget") -public class JsWidget { +public class JsWidget extends HasEventHandling implements ServerObject, WidgetMessageDetails { + @JsProperty(namespace = "dh.Widget") + public static final String EVENT_MESSAGE = "message"; + @JsProperty(namespace = "dh.Widget") + public static final String EVENT_CLOSE = "close"; + private final WorkerConnection connection; - private final WidgetFetch fetch; - private Ticket ticket; + private final TypedTicket typedTicket; - @JsFunction - public interface WidgetFetchCallback { - void handleResponse(Object error, FetchObjectResponse response, Ticket requestedTicket); - } - @JsFunction - public interface WidgetFetch { - void fetch(WidgetFetchCallback callback); - } + private boolean hasFetched; - private FetchObjectResponse response; + private final Supplier> streamFactory; + private BiDiStream messageStream; - private JsWidgetExportedObject[] exportedObjects; + private StreamResponse response; - public JsWidget(WorkerConnection connection, WidgetFetch fetch) { + private JsArray exportedObjects; + + public JsWidget(WorkerConnection connection, TypedTicket typedTicket) { this.connection = connection; - this.fetch = fetch; + this.typedTicket = typedTicket; + hasFetched = false; + BiDiStream.Factory factory = connection.streamFactory(); + streamFactory = () -> factory.create( + connection.objectServiceClient()::messageStream, + (first, headers) -> connection.objectServiceClient().openMessageStream(first, headers), + (next, headers, c) -> connection.objectServiceClient().nextMessageStream(next, headers, c::apply), + new StreamRequest()); + this.exportedObjects = new JsArray<>(); + } + + private void closeStream() { + if (messageStream != null) { + messageStream.end(); + messageStream = null; + } + hasFetched = false; + } + + /** + * Ends the client connection to the server. + */ + @JsMethod + public void close() { + suppressEvents(); + closeStream(); } public Promise refetch() { + closeStream(); return new Promise<>((resolve, reject) -> { - fetch.fetch((err, response, ticket) -> { - if (err != null) { - reject.onInvoke(err); - } else { - this.response = response; - this.ticket = ticket; + exportedObjects = new JsArray<>(); + + messageStream = streamFactory.get(); + messageStream.onData(res -> { + + JsArray responseObjects = res.getData().getExportedReferencesList() + .map((p0, p1, p2) -> new JsWidgetExportedObject(connection, p0)); + if (!hasFetched) { + response = res; + exportedObjects = responseObjects; + + hasFetched = true; resolve.onInvoke(this); + } else { + CustomEventInit messageEvent = CustomEventInit.create(); + messageEvent.setDetail(new EventDetails(res.getData(), responseObjects)); + fireEvent(EVENT_MESSAGE, messageEvent); } }); + messageStream.onStatus(status -> { + if (!status.isOk()) { + reject.onInvoke(status.getDetails()); + fireEvent(EVENT_CLOSE); + closeStream(); + } + }); + messageStream.onEnd(status -> { + closeStream(); + }); + + // First message establishes a connection w/ the plugin object instance we're talking to + StreamRequest req = new StreamRequest(); + ConnectRequest data = new ConnectRequest(); + data.setSourceId(typedTicket); + req.setConnect(data); + messageStream.send(req); }); } public Ticket getTicket() { - return ticket; + return typedTicket.getTicket(); } + /** + * @return the type of this widget + */ @JsProperty public String getType() { - return response.getType(); + return typedTicket.getType(); } + @Override + public TypedTicket typedTicket() { + TypedTicket typedTicket = new TypedTicket(); + typedTicket.setTicket(getTicket()); + typedTicket.setType(getType()); + return typedTicket; + } + + @Override @JsMethod public String getDataAsBase64() { - return response.getData_asB64(); + return response.getData().getPayload_asB64(); } + @Override @JsMethod public Uint8Array getDataAsU8() { - return response.getData_asU8(); + return response.getData().getPayload_asU8(); } + @Override + @JsMethod + public String getDataAsString() { + return new String(Js.uncheckedCast(response.getData().getPayload_asU8()), StandardCharsets.UTF_8); + } + + @Override @JsProperty public JsWidgetExportedObject[] getExportedObjects() { - if (this.exportedObjects == null) { - this.exportedObjects = response.getTypedExportIdList().asList().stream() - .map(ticket -> new JsWidgetExportedObject(connection, ticket)) - .toArray(JsWidgetExportedObject[]::new); + return Js.uncheckedCast(exportedObjects); + } + + @TsUnion + @JsType(name = "?", namespace = JsPackage.GLOBAL, isNative = true) + public interface MessageUnion { + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; } - return this.exportedObjects; + @JsOverlay + default boolean isArrayBuffer() { + return this instanceof ArrayBuffer; + } + + @JsOverlay + default boolean isView() { + return ArrayBuffer.isView(this); + } + + @JsOverlay + @TsUnionMember + default String asString() { + return Js.asString(this); + } + + @JsOverlay + @TsUnionMember + default ArrayBuffer asArrayBuffer() { + return Js.cast(this); + } + + @JsOverlay + @TsUnionMember + default ArrayBufferView asView() { + // This must be unchecked because there is no type in JS with this name + return Js.uncheckedCast(this); + } + } + + /** + * Sends a string/bytes payload to the server, along with references to objects that exist on the server. + * + * @param msg string/buffer/view instance that represents data to send + * @param references an array of objects that can be safely sent to the server + */ + @JsMethod + public void sendMessage(MessageUnion msg, + @JsOptional JsArray<@TsTypeRef(ServerObject.Union.class) ServerObject> references) { + if (messageStream == null) { + return; + } + StreamRequest req = new StreamRequest(); + Data data = new Data(); + if (msg.isString()) { + byte[] bytes = msg.asString().getBytes(StandardCharsets.UTF_8); + Uint8Array payload = new Uint8Array(bytes.length); + payload.set(Js.uncheckedCast(bytes)); + data.setPayload(payload); + } else if (msg.isArrayBuffer()) { + data.setPayload(new Uint8Array(msg.asArrayBuffer())); + } else if (msg.isView()) { + // can cast (unsafely) to any typed array or to DataView to read offset/length/buffer to make a new view + ArrayBufferView view = msg.asView(); + data.setPayload(new Uint8Array(view.buffer, view.byteOffset, view.byteLength)); + } else { + throw new IllegalArgumentException("Expected message to be a String or ArrayBuffer"); + } + + for (int i = 0; references != null && i < references.length; i++) { + ServerObject reference = references.getAt(i); + data.addExportedReferences(reference.typedTicket()); + } + + req.setData(data); + messageStream.send(req); + } + + /** + * Event details to convey a response from the server. + */ + @TsName(namespace = "dh", name = "WidgetMessageDetails") + private static class EventDetails implements WidgetMessageDetails { + private final Data data; + private final JsArray exportedObjects; + + public EventDetails(Data data, JsArray exports) { + this.data = data; + this.exportedObjects = exports; + } + + @Override + public String getDataAsBase64() { + return data.getPayload_asB64(); + } + + @Override + public Uint8Array getDataAsU8() { + return data.getPayload_asU8(); + } + + @Override + public String getDataAsString() { + return new String(Js.uncheckedCast(data.getPayload_asU8()), StandardCharsets.UTF_8); + } + + @Override + public JsWidgetExportedObject[] getExportedObjects() { + return Js.uncheckedCast(exportedObjects); + } } } diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidgetExportedObject.java b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidgetExportedObject.java index b079e688b8b..a8948d990fa 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidgetExportedObject.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidgetExportedObject.java @@ -10,17 +10,21 @@ import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; import io.deephaven.web.client.api.Callbacks; import io.deephaven.web.client.api.JsTable; +import io.deephaven.web.client.api.ServerObject; import io.deephaven.web.client.api.WorkerConnection; -import io.deephaven.web.client.api.console.JsVariableChanges; import io.deephaven.web.client.api.console.JsVariableDefinition; import io.deephaven.web.client.api.console.JsVariableType; import io.deephaven.web.client.state.ClientTableState; import jsinterop.annotations.JsMethod; import jsinterop.annotations.JsProperty; +/** + * Represents a server-side object that may not yet have been fetched by the client. Does not memoize its result, so + * fetch() should only be called once, and calling close() on this object will also close the result of the fetch. + */ @TsInterface @TsName(namespace = "dh", name = "WidgetExportedObject") -public class JsWidgetExportedObject { +public class JsWidgetExportedObject implements ServerObject { private final WorkerConnection connection; private final TypedTicket ticket; @@ -35,6 +39,14 @@ public String getType() { return ticket.getType(); } + @Override + public TypedTicket typedTicket() { + TypedTicket typedTicket = new TypedTicket(); + typedTicket.setTicket(ticket.getTicket()); + typedTicket.setType(getType()); + return typedTicket; + } + @JsMethod public Promise fetch() { if (getType().equals(JsVariableType.TABLE)) { @@ -54,4 +66,13 @@ public Promise fetch() { new JsVariableDefinition(ticket.getType(), null, ticket.getTicket().getTicket_asB64(), null)); } } + + /** + * Releases the server-side resources associated with this object, regardless of whether or not other client-side + * objects exist that also use that object. + */ + @JsMethod + public void close() { + connection.releaseTicket(ticket.getTicket()); + } } diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/widget/WidgetMessageDetails.java b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/WidgetMessageDetails.java new file mode 100644 index 00000000000..2ea701f453b --- /dev/null +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/WidgetMessageDetails.java @@ -0,0 +1,40 @@ +package io.deephaven.web.client.api.widget; + +import com.vertispan.tsdefs.annotations.TsInterface; +import elemental2.core.Uint8Array; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; + +/** + * Represents the contents of a single widget data message from the server, with a binary data paylod and exported + * objects. Implemented both by Widget itself and by the {@code event.details} when data is received by the client. + * + * Terminology note: the name of this type should probably use "Data" instead of "Message", and the methods should use + * "payload" rather than "data" to match other platforms and the protobuf itself. These names are instead used for + * backwards compatibility and to better follow JS expectations. + */ +@JsType(namespace = "dh", name = "WidgetMessageDetails") +@TsInterface +public interface WidgetMessageDetails { + /** + * Returns the data from this message as a base64-encoded string. + */ + String getDataAsBase64(); + + /** + * Returns the data from this message as a Uint8Array. + */ + Uint8Array getDataAsU8(); + + /** + * Returns the data from this message as a utf-8 string. + */ + String getDataAsString(); + + /** + * Returns an array of exported objects sent from the server. The plugin implementation is now responsible for these + * objects, and should close them when no longer needed. + */ + @JsProperty + JsWidgetExportedObject[] getExportedObjects(); +} diff --git a/web/client-api/src/main/java/io/deephaven/web/client/api/widget/plot/JsFigure.java b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/plot/JsFigure.java index 75e7b17f5d3..f373494f1bc 100644 --- a/web/client-api/src/main/java/io/deephaven/web/client/api/widget/plot/JsFigure.java +++ b/web/client-api/src/main/java/io/deephaven/web/client/api/widget/plot/JsFigure.java @@ -9,7 +9,6 @@ import elemental2.promise.Promise; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.FigureDescriptor; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.figuredescriptor.AxisDescriptor; -import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectRequest; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ExportedTableCreationResponse; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; @@ -71,6 +70,9 @@ * downsamplefinished will be fired. These events will repeat when the range changes, such as when zooming, * panning, or resizing the figure. Finally, downsamplefailed indicates that something when wrong when * downsampling, or possibly that downsampling cannot be disabled due to the number of rows in the table. + * + * At this time, not marked as a ServerObject, due to internal implementation issues which leave the door open to + * client-created figures. */ @JsType(name = "Figure", namespace = "dh.plot") public class JsFigure extends HasLifecycle { @@ -756,16 +758,16 @@ private static class DefaultFigureTableFetch implements FigureTableFetch { } @Override - public Promise fetch(JsFigure figure, FetchObjectResponse response) { + public Promise fetch(JsFigure figure, FetchObjectResponse response) { JsTable[] tables = new JsTable[0]; JsPartitionedTable[] partitionedTables = new JsPartitionedTable[0]; - Promise[] promises = new Promise[response.getTypedExportIdList().length]; + Promise[] promises = new Promise[response.getTypedExportIdsList().length]; int nextTableIndex = 0; int nextPartitionedTableIndex = 0; - for (int i = 0; i < response.getTypedExportIdList().length; i++) { - TypedTicket ticket = response.getTypedExportIdList().getAt(i); + for (int i = 0; i < response.getTypedExportIdsList().length; i++) { + TypedTicket ticket = response.getTypedExportIdsList().getAt(i); if (ticket.getType().equals(JsVariableType.TABLE)) { // Note that creating a CTS like this means we can't actually refetch it, but that's okay, we can't // reconnect in this way without refetching the entire figure anyway. @@ -785,22 +787,14 @@ public Promise fetch(JsFigure figure, FetchObjectResponse response) { }); } else if (ticket.getType().equals(JsVariableType.PARTITIONEDTABLE)) { int partitionedTableIndex = nextPartitionedTableIndex++; - promises[i] = Callbacks.grpcUnaryPromise(c -> { - FetchObjectRequest partitionedTableRequest = new FetchObjectRequest(); - partitionedTableRequest.setSourceId(ticket); - connection.objectServiceClient().fetchObject(partitionedTableRequest, connection.metadata(), - c::apply); - }).then(object -> { - JsPartitionedTable partitionedTable = - new JsPartitionedTable(connection, new JsWidget(connection, - callback -> callback.handleResponse(null, object, ticket.getTicket()))); - // TODO(deephaven-core#3604) if using a new session don't attempt a reconnect, since we might - // have a different figure schema entirely - // partitionedTable.addEventListener(JsPartitionedTable.EVENT_DISCONNECT, ignore -> - // partitionedTable.close()); - partitionedTables[partitionedTableIndex] = partitionedTable; - return partitionedTable.refetch(); - }); + JsPartitionedTable partitionedTable = + new JsPartitionedTable(connection, new JsWidget(connection, ticket)); + // TODO(deephaven-core#3604) if using a new session don't attempt a reconnect, since we might + // have a different figure schema entirely + // partitionedTable.addEventListener(JsPartitionedTable.EVENT_DISCONNECT, ignore -> + // partitionedTable.close()); + partitionedTables[partitionedTableIndex] = partitionedTable; + promises[i] = partitionedTable.refetch(); } else { throw new IllegalStateException("Ticket type not recognized in a Figure: " + ticket.getType()); } diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/BrowserNextResponse.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/BrowserNextResponse.java new file mode 100644 index 00000000000..d29b4a1d0be --- /dev/null +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/BrowserNextResponse.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending + */ +package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb; + +import elemental2.core.Uint8Array; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsType; + +@JsType( + isNative = true, + name = "dhinternal.io.deephaven.proto.object_pb.BrowserNextResponse", + namespace = JsPackage.GLOBAL) +public class BrowserNextResponse { + public static native BrowserNextResponse deserializeBinary(Uint8Array bytes); + + public static native BrowserNextResponse deserializeBinaryFromReader( + BrowserNextResponse message, Object reader); + + public static native void serializeBinaryToWriter(BrowserNextResponse message, Object writer); + + public static native Object toObject(boolean includeInstance, BrowserNextResponse msg); + + public native Uint8Array serializeBinary(); + + public native Object toObject(); + + public native Object toObject(boolean includeInstance); +} diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/ConnectRequest.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/ConnectRequest.java new file mode 100644 index 00000000000..e7eda1989ae --- /dev/null +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/ConnectRequest.java @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending + */ +package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb; + +import elemental2.core.Uint8Array; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; +import jsinterop.base.Js; +import jsinterop.base.JsPropertyMap; + +@JsType( + isNative = true, + name = "dhinternal.io.deephaven.proto.object_pb.ConnectRequest", + namespace = JsPackage.GLOBAL) +public class ConnectRequest { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface SourceIdFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static ConnectRequest.ToObjectReturnType.SourceIdFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static ConnectRequest.ToObjectReturnType.SourceIdFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + ConnectRequest.ToObjectReturnType.SourceIdFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + ConnectRequest.ToObjectReturnType.SourceIdFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static ConnectRequest.ToObjectReturnType.SourceIdFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + ConnectRequest.ToObjectReturnType.SourceIdFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket(ConnectRequest.ToObjectReturnType.SourceIdFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsOverlay + static ConnectRequest.ToObjectReturnType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + ConnectRequest.ToObjectReturnType.SourceIdFieldType getSourceId(); + + @JsProperty + void setSourceId(ConnectRequest.ToObjectReturnType.SourceIdFieldType sourceId); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType0 { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface SourceIdFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static ConnectRequest.ToObjectReturnType0.SourceIdFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static ConnectRequest.ToObjectReturnType0.SourceIdFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + ConnectRequest.ToObjectReturnType0.SourceIdFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + ConnectRequest.ToObjectReturnType0.SourceIdFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static ConnectRequest.ToObjectReturnType0.SourceIdFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + ConnectRequest.ToObjectReturnType0.SourceIdFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket(ConnectRequest.ToObjectReturnType0.SourceIdFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsOverlay + static ConnectRequest.ToObjectReturnType0 create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + ConnectRequest.ToObjectReturnType0.SourceIdFieldType getSourceId(); + + @JsProperty + void setSourceId(ConnectRequest.ToObjectReturnType0.SourceIdFieldType sourceId); + } + + public static native ConnectRequest deserializeBinary(Uint8Array bytes); + + public static native ConnectRequest deserializeBinaryFromReader( + ConnectRequest message, Object reader); + + public static native void serializeBinaryToWriter(ConnectRequest message, Object writer); + + public static native ConnectRequest.ToObjectReturnType toObject( + boolean includeInstance, ConnectRequest msg); + + public native void clearSourceId(); + + public native TypedTicket getSourceId(); + + public native boolean hasSourceId(); + + public native Uint8Array serializeBinary(); + + public native void setSourceId(); + + public native void setSourceId(TypedTicket value); + + public native ConnectRequest.ToObjectReturnType0 toObject(); + + public native ConnectRequest.ToObjectReturnType0 toObject(boolean includeInstance); +} diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/Data.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/Data.java new file mode 100644 index 00000000000..811f57ffefe --- /dev/null +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/Data.java @@ -0,0 +1,417 @@ +/** + * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending + */ +package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb; + +import elemental2.core.JsArray; +import elemental2.core.Uint8Array; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket; +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; +import jsinterop.base.Js; +import jsinterop.base.JsPropertyMap; + +@JsType( + isNative = true, + name = "dhinternal.io.deephaven.proto.object_pb.Data", + namespace = JsPackage.GLOBAL) +public class Data { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetPayloadUnionType { + @JsOverlay + static Data.GetPayloadUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface SetPayloadValueUnionType { + @JsOverlay + static Data.SetPayloadValueUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ExportedReferencesListFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static Data.ToObjectReturnType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static Data.ToObjectReturnType.ExportedReferencesListFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + Data.ToObjectReturnType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + Data.ToObjectReturnType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static Data.ToObjectReturnType.ExportedReferencesListFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + Data.ToObjectReturnType.ExportedReferencesListFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket( + Data.ToObjectReturnType.ExportedReferencesListFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetPayloadUnionType { + @JsOverlay + static Data.ToObjectReturnType.GetPayloadUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static Data.ToObjectReturnType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + JsArray getExportedReferencesList(); + + @JsProperty + Data.ToObjectReturnType.GetPayloadUnionType getPayload(); + + @JsOverlay + default void setExportedReferencesList( + Data.ToObjectReturnType.ExportedReferencesListFieldType[] exportedReferencesList) { + setExportedReferencesList( + Js.>uncheckedCast( + exportedReferencesList)); + } + + @JsProperty + void setExportedReferencesList( + JsArray exportedReferencesList); + + @JsProperty + void setPayload(Data.ToObjectReturnType.GetPayloadUnionType payload); + + @JsOverlay + default void setPayload(String payload) { + setPayload(Js.uncheckedCast(payload)); + } + + @JsOverlay + default void setPayload(Uint8Array payload) { + setPayload(Js.uncheckedCast(payload)); + } + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType0 { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ExportedReferencesListFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static Data.ToObjectReturnType0.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static Data.ToObjectReturnType0.ExportedReferencesListFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + Data.ToObjectReturnType0.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + Data.ToObjectReturnType0.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static Data.ToObjectReturnType0.ExportedReferencesListFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + Data.ToObjectReturnType0.ExportedReferencesListFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket( + Data.ToObjectReturnType0.ExportedReferencesListFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetPayloadUnionType { + @JsOverlay + static Data.ToObjectReturnType0.GetPayloadUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static Data.ToObjectReturnType0 create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + JsArray getExportedReferencesList(); + + @JsProperty + Data.ToObjectReturnType0.GetPayloadUnionType getPayload(); + + @JsOverlay + default void setExportedReferencesList( + Data.ToObjectReturnType0.ExportedReferencesListFieldType[] exportedReferencesList) { + setExportedReferencesList( + Js.>uncheckedCast( + exportedReferencesList)); + } + + @JsProperty + void setExportedReferencesList( + JsArray exportedReferencesList); + + @JsProperty + void setPayload(Data.ToObjectReturnType0.GetPayloadUnionType payload); + + @JsOverlay + default void setPayload(String payload) { + setPayload(Js.uncheckedCast(payload)); + } + + @JsOverlay + default void setPayload(Uint8Array payload) { + setPayload(Js.uncheckedCast(payload)); + } + } + + public static native Data deserializeBinary(Uint8Array bytes); + + public static native Data deserializeBinaryFromReader(Data message, Object reader); + + public static native void serializeBinaryToWriter(Data message, Object writer); + + public static native Data.ToObjectReturnType toObject(boolean includeInstance, Data msg); + + public native TypedTicket addExportedReferences(); + + public native TypedTicket addExportedReferences(TypedTicket value, double index); + + public native TypedTicket addExportedReferences(TypedTicket value); + + public native void clearExportedReferencesList(); + + public native JsArray getExportedReferencesList(); + + public native Data.GetPayloadUnionType getPayload(); + + public native String getPayload_asB64(); + + public native Uint8Array getPayload_asU8(); + + public native Uint8Array serializeBinary(); + + public native void setExportedReferencesList(JsArray value); + + @JsOverlay + public final void setExportedReferencesList(TypedTicket[] value) { + setExportedReferencesList(Js.>uncheckedCast(value)); + } + + public native void setPayload(Data.SetPayloadValueUnionType value); + + @JsOverlay + public final void setPayload(String value) { + setPayload(Js.uncheckedCast(value)); + } + + @JsOverlay + public final void setPayload(Uint8Array value) { + setPayload(Js.uncheckedCast(value)); + } + + public native Data.ToObjectReturnType0 toObject(); + + public native Data.ToObjectReturnType0 toObject(boolean includeInstance); +} diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/FetchObjectResponse.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/FetchObjectResponse.java index 881fef078b3..fb39794f006 100644 --- a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/FetchObjectResponse.java +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/FetchObjectResponse.java @@ -105,13 +105,13 @@ default boolean isUint8Array() { } @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) - public interface TypedExportIdListFieldType { + public interface TypedExportIdsListFieldType { @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) public interface TicketFieldType { @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) public interface GetTicketUnionType { @JsOverlay - static FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType.TicketFieldType.GetTicketUnionType of( + static FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType.TicketFieldType.GetTicketUnionType of( Object o) { return Js.cast(o); } @@ -138,46 +138,46 @@ default boolean isUint8Array() { } @JsOverlay - static FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType.TicketFieldType create() { + static FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType.TicketFieldType create() { return Js.uncheckedCast(JsPropertyMap.of()); } @JsProperty - FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType.TicketFieldType.GetTicketUnionType getTicket(); + FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType.TicketFieldType.GetTicketUnionType getTicket(); @JsProperty void setTicket( - FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType.TicketFieldType.GetTicketUnionType ticket); + FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType.TicketFieldType.GetTicketUnionType ticket); @JsOverlay default void setTicket(String ticket) { setTicket( - Js.uncheckedCast( + Js.uncheckedCast( ticket)); } @JsOverlay default void setTicket(Uint8Array ticket) { setTicket( - Js.uncheckedCast( + Js.uncheckedCast( ticket)); } } @JsOverlay - static FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType create() { + static FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType create() { return Js.uncheckedCast(JsPropertyMap.of()); } @JsProperty - FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType.TicketFieldType getTicket(); + FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType.TicketFieldType getTicket(); @JsProperty String getType(); @JsProperty void setTicket( - FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType.TicketFieldType ticket); + FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType.TicketFieldType ticket); @JsProperty void setType(String type); @@ -195,7 +195,7 @@ static FetchObjectResponse.ToObjectReturnType create() { String getType(); @JsProperty - JsArray getTypedExportIdList(); + JsArray getTypedExportIdsList(); @JsProperty void setData(FetchObjectResponse.ToObjectReturnType.GetDataUnionType data); @@ -214,15 +214,15 @@ default void setData(Uint8Array data) { void setType(String type); @JsProperty - void setTypedExportIdList( - JsArray typedExportIdList); + void setTypedExportIdsList( + JsArray typedExportIdsList); @JsOverlay - default void setTypedExportIdList( - FetchObjectResponse.ToObjectReturnType.TypedExportIdListFieldType[] typedExportIdList) { - setTypedExportIdList( - Js.>uncheckedCast( - typedExportIdList)); + default void setTypedExportIdsList( + FetchObjectResponse.ToObjectReturnType.TypedExportIdsListFieldType[] typedExportIdsList) { + setTypedExportIdsList( + Js.>uncheckedCast( + typedExportIdsList)); } } @@ -257,13 +257,13 @@ default boolean isUint8Array() { } @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) - public interface TypedExportIdListFieldType { + public interface TypedExportIdsListFieldType { @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) public interface TicketFieldType { @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) public interface GetTicketUnionType { @JsOverlay - static FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType.TicketFieldType.GetTicketUnionType of( + static FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType.TicketFieldType.GetTicketUnionType of( Object o) { return Js.cast(o); } @@ -290,46 +290,46 @@ default boolean isUint8Array() { } @JsOverlay - static FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType.TicketFieldType create() { + static FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType.TicketFieldType create() { return Js.uncheckedCast(JsPropertyMap.of()); } @JsProperty - FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType.TicketFieldType.GetTicketUnionType getTicket(); + FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType.TicketFieldType.GetTicketUnionType getTicket(); @JsProperty void setTicket( - FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType.TicketFieldType.GetTicketUnionType ticket); + FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType.TicketFieldType.GetTicketUnionType ticket); @JsOverlay default void setTicket(String ticket) { setTicket( - Js.uncheckedCast( + Js.uncheckedCast( ticket)); } @JsOverlay default void setTicket(Uint8Array ticket) { setTicket( - Js.uncheckedCast( + Js.uncheckedCast( ticket)); } } @JsOverlay - static FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType create() { + static FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType create() { return Js.uncheckedCast(JsPropertyMap.of()); } @JsProperty - FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType.TicketFieldType getTicket(); + FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType.TicketFieldType getTicket(); @JsProperty String getType(); @JsProperty void setTicket( - FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType.TicketFieldType ticket); + FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType.TicketFieldType ticket); @JsProperty void setType(String type); @@ -347,7 +347,7 @@ static FetchObjectResponse.ToObjectReturnType0 create() { String getType(); @JsProperty - JsArray getTypedExportIdList(); + JsArray getTypedExportIdsList(); @JsProperty void setData(FetchObjectResponse.ToObjectReturnType0.GetDataUnionType data); @@ -366,15 +366,15 @@ default void setData(Uint8Array data) { void setType(String type); @JsProperty - void setTypedExportIdList( - JsArray typedExportIdList); + void setTypedExportIdsList( + JsArray typedExportIdsList); @JsOverlay - default void setTypedExportIdList( - FetchObjectResponse.ToObjectReturnType0.TypedExportIdListFieldType[] typedExportIdList) { - setTypedExportIdList( - Js.>uncheckedCast( - typedExportIdList)); + default void setTypedExportIdsList( + FetchObjectResponse.ToObjectReturnType0.TypedExportIdsListFieldType[] typedExportIdsList) { + setTypedExportIdsList( + Js.>uncheckedCast( + typedExportIdsList)); } } @@ -388,13 +388,13 @@ public static native FetchObjectResponse deserializeBinaryFromReader( public static native FetchObjectResponse.ToObjectReturnType toObject( boolean includeInstance, FetchObjectResponse msg); - public native TypedTicket addTypedExportId(); + public native TypedTicket addTypedExportIds(); - public native TypedTicket addTypedExportId(TypedTicket value, double index); + public native TypedTicket addTypedExportIds(TypedTicket value, double index); - public native TypedTicket addTypedExportId(TypedTicket value); + public native TypedTicket addTypedExportIds(TypedTicket value); - public native void clearTypedExportIdList(); + public native void clearTypedExportIdsList(); public native FetchObjectResponse.GetDataUnionType getData(); @@ -404,7 +404,7 @@ public static native FetchObjectResponse.ToObjectReturnType toObject( public native String getType(); - public native JsArray getTypedExportIdList(); + public native JsArray getTypedExportIdsList(); public native Uint8Array serializeBinary(); @@ -422,11 +422,11 @@ public final void setData(Uint8Array value) { public native void setType(String value); - public native void setTypedExportIdList(JsArray value); + public native void setTypedExportIdsList(JsArray value); @JsOverlay - public final void setTypedExportIdList(TypedTicket[] value) { - setTypedExportIdList(Js.>uncheckedCast(value)); + public final void setTypedExportIdsList(TypedTicket[] value) { + setTypedExportIdsList(Js.>uncheckedCast(value)); } public native FetchObjectResponse.ToObjectReturnType0 toObject(); diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamRequest.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamRequest.java new file mode 100644 index 00000000000..89aae2e50fb --- /dev/null +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamRequest.java @@ -0,0 +1,419 @@ +/** + * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending + */ +package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb; + +import elemental2.core.JsArray; +import elemental2.core.Uint8Array; +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; +import jsinterop.base.Js; +import jsinterop.base.JsPropertyMap; + +@JsType( + isNative = true, + name = "dhinternal.io.deephaven.proto.object_pb.StreamRequest", + namespace = JsPackage.GLOBAL) +public class StreamRequest { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ConnectFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface SourceIdFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket( + StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsOverlay + static StreamRequest.ToObjectReturnType.ConnectFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType getSourceId(); + + @JsProperty + void setSourceId( + StreamRequest.ToObjectReturnType.ConnectFieldType.SourceIdFieldType sourceId); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface DataFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetPayloadUnionType { + @JsOverlay + static StreamRequest.ToObjectReturnType.DataFieldType.GetPayloadUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType.DataFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + JsArray getExportedReferencesList(); + + @JsProperty + StreamRequest.ToObjectReturnType.DataFieldType.GetPayloadUnionType getPayload(); + + @JsProperty + void setExportedReferencesList(JsArray exportedReferencesList); + + @JsOverlay + default void setExportedReferencesList(Object[] exportedReferencesList) { + setExportedReferencesList(Js.>uncheckedCast(exportedReferencesList)); + } + + @JsProperty + void setPayload(StreamRequest.ToObjectReturnType.DataFieldType.GetPayloadUnionType payload); + + @JsOverlay + default void setPayload(String payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + + @JsOverlay + default void setPayload(Uint8Array payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType.ConnectFieldType getConnect(); + + @JsProperty + StreamRequest.ToObjectReturnType.DataFieldType getData(); + + @JsProperty + void setConnect(StreamRequest.ToObjectReturnType.ConnectFieldType connect); + + @JsProperty + void setData(StreamRequest.ToObjectReturnType.DataFieldType data); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType0 { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ConnectFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface SourceIdFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket( + StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsOverlay + static StreamRequest.ToObjectReturnType0.ConnectFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType getSourceId(); + + @JsProperty + void setSourceId( + StreamRequest.ToObjectReturnType0.ConnectFieldType.SourceIdFieldType sourceId); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface DataFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetPayloadUnionType { + @JsOverlay + static StreamRequest.ToObjectReturnType0.DataFieldType.GetPayloadUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType0.DataFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + JsArray getExportedReferencesList(); + + @JsProperty + StreamRequest.ToObjectReturnType0.DataFieldType.GetPayloadUnionType getPayload(); + + @JsProperty + void setExportedReferencesList(JsArray exportedReferencesList); + + @JsOverlay + default void setExportedReferencesList(Object[] exportedReferencesList) { + setExportedReferencesList(Js.>uncheckedCast(exportedReferencesList)); + } + + @JsProperty + void setPayload(StreamRequest.ToObjectReturnType0.DataFieldType.GetPayloadUnionType payload); + + @JsOverlay + default void setPayload(String payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + + @JsOverlay + default void setPayload(Uint8Array payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + } + + @JsOverlay + static StreamRequest.ToObjectReturnType0 create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamRequest.ToObjectReturnType0.ConnectFieldType getConnect(); + + @JsProperty + StreamRequest.ToObjectReturnType0.DataFieldType getData(); + + @JsProperty + void setConnect(StreamRequest.ToObjectReturnType0.ConnectFieldType connect); + + @JsProperty + void setData(StreamRequest.ToObjectReturnType0.DataFieldType data); + } + + public static native StreamRequest deserializeBinary(Uint8Array bytes); + + public static native StreamRequest deserializeBinaryFromReader( + StreamRequest message, Object reader); + + public static native void serializeBinaryToWriter(StreamRequest message, Object writer); + + public static native StreamRequest.ToObjectReturnType toObject( + boolean includeInstance, StreamRequest msg); + + public native void clearConnect(); + + public native void clearData(); + + public native ConnectRequest getConnect(); + + public native Data getData(); + + public native int getMessageCase(); + + public native boolean hasConnect(); + + public native boolean hasData(); + + public native Uint8Array serializeBinary(); + + public native void setConnect(); + + public native void setConnect(ConnectRequest value); + + public native void setData(); + + public native void setData(Data value); + + public native StreamRequest.ToObjectReturnType0 toObject(); + + public native StreamRequest.ToObjectReturnType0 toObject(boolean includeInstance); +} diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamResponse.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamResponse.java new file mode 100644 index 00000000000..bc92811e103 --- /dev/null +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/StreamResponse.java @@ -0,0 +1,375 @@ +/** + * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending + */ +package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb; + +import elemental2.core.JsArray; +import elemental2.core.Uint8Array; +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; +import jsinterop.base.Js; +import jsinterop.base.JsPropertyMap; + +@JsType( + isNative = true, + name = "dhinternal.io.deephaven.proto.object_pb.StreamResponse", + namespace = JsPackage.GLOBAL) +public class StreamResponse { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface DataFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ExportedReferencesListFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket( + StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetPayloadUnionType { + @JsOverlay + static StreamResponse.ToObjectReturnType.DataFieldType.GetPayloadUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType.DataFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + JsArray getExportedReferencesList(); + + @JsProperty + StreamResponse.ToObjectReturnType.DataFieldType.GetPayloadUnionType getPayload(); + + @JsOverlay + default void setExportedReferencesList( + StreamResponse.ToObjectReturnType.DataFieldType.ExportedReferencesListFieldType[] exportedReferencesList) { + setExportedReferencesList( + Js.>uncheckedCast( + exportedReferencesList)); + } + + @JsProperty + void setExportedReferencesList( + JsArray exportedReferencesList); + + @JsProperty + void setPayload(StreamResponse.ToObjectReturnType.DataFieldType.GetPayloadUnionType payload); + + @JsOverlay + default void setPayload(String payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + + @JsOverlay + default void setPayload(Uint8Array payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamResponse.ToObjectReturnType.DataFieldType getData(); + + @JsProperty + void setData(StreamResponse.ToObjectReturnType.DataFieldType data); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ToObjectReturnType0 { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface DataFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface ExportedReferencesListFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface TicketFieldType { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetTicketUnionType { + @JsOverlay + static StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType of( + Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType.TicketFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType getTicket(); + + @JsProperty + void setTicket( + StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType.TicketFieldType.GetTicketUnionType ticket); + + @JsOverlay + default void setTicket(String ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + + @JsOverlay + default void setTicket(Uint8Array ticket) { + setTicket( + Js.uncheckedCast( + ticket)); + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType.TicketFieldType getTicket(); + + @JsProperty + String getType(); + + @JsProperty + void setTicket( + StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType.TicketFieldType ticket); + + @JsProperty + void setType(String type); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface GetPayloadUnionType { + @JsOverlay + static StreamResponse.ToObjectReturnType0.DataFieldType.GetPayloadUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default Uint8Array asUint8Array() { + return Js.cast(this); + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + + @JsOverlay + default boolean isUint8Array() { + return (Object) this instanceof Uint8Array; + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType0.DataFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + JsArray getExportedReferencesList(); + + @JsProperty + StreamResponse.ToObjectReturnType0.DataFieldType.GetPayloadUnionType getPayload(); + + @JsOverlay + default void setExportedReferencesList( + StreamResponse.ToObjectReturnType0.DataFieldType.ExportedReferencesListFieldType[] exportedReferencesList) { + setExportedReferencesList( + Js.>uncheckedCast( + exportedReferencesList)); + } + + @JsProperty + void setExportedReferencesList( + JsArray exportedReferencesList); + + @JsProperty + void setPayload(StreamResponse.ToObjectReturnType0.DataFieldType.GetPayloadUnionType payload); + + @JsOverlay + default void setPayload(String payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + + @JsOverlay + default void setPayload(Uint8Array payload) { + setPayload( + Js.uncheckedCast( + payload)); + } + } + + @JsOverlay + static StreamResponse.ToObjectReturnType0 create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + StreamResponse.ToObjectReturnType0.DataFieldType getData(); + + @JsProperty + void setData(StreamResponse.ToObjectReturnType0.DataFieldType data); + } + + public static native StreamResponse deserializeBinary(Uint8Array bytes); + + public static native StreamResponse deserializeBinaryFromReader( + StreamResponse message, Object reader); + + public static native void serializeBinaryToWriter(StreamResponse message, Object writer); + + public static native StreamResponse.ToObjectReturnType toObject( + boolean includeInstance, StreamResponse msg); + + public native void clearData(); + + public native Data getData(); + + public native int getMessageCase(); + + public native boolean hasData(); + + public native Uint8Array serializeBinary(); + + public native void setData(); + + public native void setData(Data value); + + public native StreamResponse.ToObjectReturnType0 toObject(); + + public native StreamResponse.ToObjectReturnType0 toObject(boolean includeInstance); +} diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamrequest/MessageCase.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamrequest/MessageCase.java new file mode 100644 index 00000000000..0ff4a2638fe --- /dev/null +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamrequest/MessageCase.java @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending + */ +package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.streamrequest; + +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsType; + +@JsType( + isNative = true, + name = "dhinternal.io.deephaven.proto.object_pb.StreamRequest.MessageCase", + namespace = JsPackage.GLOBAL) +public class MessageCase { + public static int CONNECT, DATA, MESSAGE_NOT_SET; +} diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamresponse/MessageCase.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamresponse/MessageCase.java new file mode 100644 index 00000000000..b0b77b347e5 --- /dev/null +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb/streamresponse/MessageCase.java @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending + */ +package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.streamresponse; + +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsType; + +@JsType( + isNative = true, + name = "dhinternal.io.deephaven.proto.object_pb.StreamResponse.MessageCase", + namespace = JsPackage.GLOBAL) +public class MessageCase { + public static int DATA, MESSAGE_NOT_SET; +} diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectService.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectService.java index 68ac649d2d3..90b4eef82ce 100644 --- a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectService.java +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectService.java @@ -59,6 +59,141 @@ static ObjectService.FetchObjectType create() { void setService(Object service); } + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface MessageStreamType { + @JsOverlay + static ObjectService.MessageStreamType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + String getMethodName(); + + @JsProperty + Object getRequestType(); + + @JsProperty + Object getResponseType(); + + @JsProperty + Object getService(); + + @JsProperty + boolean isRequestStream(); + + @JsProperty + boolean isResponseStream(); + + @JsProperty + void setMethodName(String methodName); + + @JsProperty + void setRequestStream(boolean requestStream); + + @JsProperty + void setRequestType(Object requestType); + + @JsProperty + void setResponseStream(boolean responseStream); + + @JsProperty + void setResponseType(Object responseType); + + @JsProperty + void setService(Object service); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface NextMessageStreamType { + @JsOverlay + static ObjectService.NextMessageStreamType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + String getMethodName(); + + @JsProperty + Object getRequestType(); + + @JsProperty + Object getResponseType(); + + @JsProperty + Object getService(); + + @JsProperty + boolean isRequestStream(); + + @JsProperty + boolean isResponseStream(); + + @JsProperty + void setMethodName(String methodName); + + @JsProperty + void setRequestStream(boolean requestStream); + + @JsProperty + void setRequestType(Object requestType); + + @JsProperty + void setResponseStream(boolean responseStream); + + @JsProperty + void setResponseType(Object responseType); + + @JsProperty + void setService(Object service); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface OpenMessageStreamType { + @JsOverlay + static ObjectService.OpenMessageStreamType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + String getMethodName(); + + @JsProperty + Object getRequestType(); + + @JsProperty + Object getResponseType(); + + @JsProperty + Object getService(); + + @JsProperty + boolean isRequestStream(); + + @JsProperty + boolean isResponseStream(); + + @JsProperty + void setMethodName(String methodName); + + @JsProperty + void setRequestStream(boolean requestStream); + + @JsProperty + void setRequestType(Object requestType); + + @JsProperty + void setResponseStream(boolean responseStream); + + @JsProperty + void setResponseType(Object responseType); + + @JsProperty + void setService(Object service); + } + public static ObjectService.FetchObjectType FetchObject; + public static ObjectService.MessageStreamType MessageStream; + public static ObjectService.NextMessageStreamType NextMessageStream; + public static ObjectService.OpenMessageStreamType OpenMessageStream; public static String serviceName; } diff --git a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectServiceClient.java b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectServiceClient.java index 86046a35bdb..7596ec87d6d 100644 --- a/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectServiceClient.java +++ b/web/client-backplane/src/main/java/io/deephaven/javascript/proto/dhinternal/io/deephaven/proto/object_pb_service/ObjectServiceClient.java @@ -4,8 +4,11 @@ package io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb_service; import io.deephaven.javascript.proto.dhinternal.browserheaders.BrowserHeaders; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.BrowserNextResponse; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectRequest; import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.StreamRequest; +import io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.StreamResponse; import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; @@ -110,6 +113,99 @@ default boolean isFetchObjectMetadata_or_callbackFn() { } } + @JsFunction + public interface NextMessageStreamCallbackFn { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface P0Type { + @JsOverlay + static ObjectServiceClient.NextMessageStreamCallbackFn.P0Type create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + double getCode(); + + @JsProperty + String getMessage(); + + @JsProperty + BrowserHeaders getMetadata(); + + @JsProperty + void setCode(double code); + + @JsProperty + void setMessage(String message); + + @JsProperty + void setMetadata(BrowserHeaders metadata); + } + + void onInvoke( + ObjectServiceClient.NextMessageStreamCallbackFn.P0Type p0, BrowserNextResponse p1); + } + + @JsFunction + public interface NextMessageStreamMetadata_or_callbackFn { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface P0Type { + @JsOverlay + static ObjectServiceClient.NextMessageStreamMetadata_or_callbackFn.P0Type create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + double getCode(); + + @JsProperty + String getMessage(); + + @JsProperty + BrowserHeaders getMetadata(); + + @JsProperty + void setCode(double code); + + @JsProperty + void setMessage(String message); + + @JsProperty + void setMetadata(BrowserHeaders metadata); + } + + void onInvoke( + ObjectServiceClient.NextMessageStreamMetadata_or_callbackFn.P0Type p0, + BrowserNextResponse p1); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface NextMessageStreamMetadata_or_callbackUnionType { + @JsOverlay + static ObjectServiceClient.NextMessageStreamMetadata_or_callbackUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default BrowserHeaders asBrowserHeaders() { + return Js.cast(this); + } + + @JsOverlay + default ObjectServiceClient.NextMessageStreamMetadata_or_callbackFn asNextMessageStreamMetadata_or_callbackFn() { + return Js.cast(this); + } + + @JsOverlay + default boolean isBrowserHeaders() { + return (Object) this instanceof BrowserHeaders; + } + + @JsOverlay + default boolean isNextMessageStreamMetadata_or_callbackFn() { + return (Object) this instanceof ObjectServiceClient.NextMessageStreamMetadata_or_callbackFn; + } + } + public String serviceHost; public ObjectServiceClient(String serviceHost, Object options) {} @@ -167,4 +263,66 @@ public native UnaryResponse fetchObject( public native UnaryResponse fetchObject( FetchObjectRequest requestMessage, ObjectServiceClient.FetchObjectMetadata_or_callbackUnionType metadata_or_callback); + + public native BidirectionalStream messageStream(); + + public native BidirectionalStream messageStream( + BrowserHeaders metadata); + + @JsOverlay + public final UnaryResponse nextMessageStream( + StreamRequest requestMessage, + BrowserHeaders metadata_or_callback, + ObjectServiceClient.NextMessageStreamCallbackFn callback) { + return nextMessageStream( + requestMessage, + Js.uncheckedCast( + metadata_or_callback), + callback); + } + + @JsOverlay + public final UnaryResponse nextMessageStream( + StreamRequest requestMessage, BrowserHeaders metadata_or_callback) { + return nextMessageStream( + requestMessage, + Js.uncheckedCast( + metadata_or_callback)); + } + + @JsOverlay + public final UnaryResponse nextMessageStream( + StreamRequest requestMessage, + ObjectServiceClient.NextMessageStreamMetadata_or_callbackFn metadata_or_callback, + ObjectServiceClient.NextMessageStreamCallbackFn callback) { + return nextMessageStream( + requestMessage, + Js.uncheckedCast( + metadata_or_callback), + callback); + } + + @JsOverlay + public final UnaryResponse nextMessageStream( + StreamRequest requestMessage, + ObjectServiceClient.NextMessageStreamMetadata_or_callbackFn metadata_or_callback) { + return nextMessageStream( + requestMessage, + Js.uncheckedCast( + metadata_or_callback)); + } + + public native UnaryResponse nextMessageStream( + StreamRequest requestMessage, + ObjectServiceClient.NextMessageStreamMetadata_or_callbackUnionType metadata_or_callback, + ObjectServiceClient.NextMessageStreamCallbackFn callback); + + public native UnaryResponse nextMessageStream( + StreamRequest requestMessage, + ObjectServiceClient.NextMessageStreamMetadata_or_callbackUnionType metadata_or_callback); + + public native ResponseStream openMessageStream( + StreamRequest requestMessage, BrowserHeaders metadata); + + public native ResponseStream openMessageStream(StreamRequest requestMessage); }