Skip to content

Commit

Permalink
GetServiceNameFromDescriptor and CreateServiceMethodInformationSet in…
Browse files Browse the repository at this point in the history
… separate unit msg/protobuf/client_protobuf_utils.h
  • Loading branch information
rex-schilasky committed Feb 6, 2025
1 parent 0cdd6e2 commit 7ff7b07
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 59 deletions.
3 changes: 2 additions & 1 deletion serialization/protobuf/protobuf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ target_sources(protobuf_core
FILES
include/ecal/msg/protobuf/client.h
include/ecal/msg/protobuf/client_instance.h
include/ecal/msg/protobuf/client_response_parser.h
include/ecal/msg/protobuf/client_protobuf_utils.h
include/ecal/msg/protobuf/client_response_parser.h
include/ecal/msg/protobuf/client_typed_response.h
include/ecal/msg/protobuf/dynamic_json_subscriber.h
include/ecal/msg/protobuf/dynamic_publisher.h
Expand Down
63 changes: 5 additions & 58 deletions serialization/protobuf/protobuf/include/ecal/msg/protobuf/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@

#include <ecal/deprecate.h>
#include <ecal/service/client.h>

#include <ecal/msg/protobuf/ecal_proto_dyn.h>
#include <ecal/msg/protobuf/client_instance.h> // our new templated CClientInstance<T>
#include <ecal/msg/protobuf/client_instance.h>
#include <ecal/msg/protobuf/client_protobuf_utils.h>

#ifdef _MSC_VER
#pragma warning(push, 0) // disable proto warnings
Expand Down Expand Up @@ -63,7 +65,7 @@ namespace eCAL
* @brief Constructor (using protobuf‐defined service name).
*/
CServiceClient(const ClientEventCallbackT& event_callback_ = ClientEventCallbackT())
: eCAL::CServiceClient(GetServiceNameFromDescriptor(), CreateServiceMethodInformationSet(), event_callback_)
: eCAL::CServiceClient(GetServiceNameFromDescriptor<T>(), CreateServiceMethodInformationSet<T>(), event_callback_)
{
}

Expand All @@ -73,7 +75,7 @@ namespace eCAL
* @param service_name_ Unique service name.
*/
explicit CServiceClient(const std::string& service_name_, const ClientEventCallbackT& event_callback_ = ClientEventCallbackT())
: eCAL::CServiceClient(service_name_, CreateServiceMethodInformationSet(), event_callback_)
: eCAL::CServiceClient(service_name_, CreateServiceMethodInformationSet<T>(), event_callback_)
{
}

Expand Down Expand Up @@ -258,61 +260,6 @@ namespace eCAL
using eCAL::CServiceClient::CallWithResponse;
using eCAL::CServiceClient::CallWithCallback;
using eCAL::CServiceClient::CallWithCallbackAsync;

private:
/**
* @brief Retrieves the full service name from the Protobuf descriptor.
*/
static std::string GetServiceNameFromDescriptor()
{
struct U : T {}; // Temporary subclass to access protected GetDescriptor()
U temp_instance;
return temp_instance.GetDescriptor()->full_name();
}

/**
* @brief Generates the method information set for the service.
*
* @return A set containing method information.
*/
static ServiceMethodInformationSetT CreateServiceMethodInformationSet()
{
struct U : T {}; // Temporary subclass to access protected GetDescriptor()
U temp_instance;
const google::protobuf::ServiceDescriptor* service_descriptor = temp_instance.GetDescriptor();

if (service_descriptor == nullptr)
{
throw std::runtime_error("Failed to retrieve service descriptor.");
}

ServiceMethodInformationSetT method_information_map;
CProtoDynDecoder dyn_decoder;
std::string error_s;

for (int i = 0; i < service_descriptor->method_count(); ++i)
{
const google::protobuf::MethodDescriptor* method_descriptor = service_descriptor->method(i);
const std::string& method_name = method_descriptor->name();

const std::string& request_type_name = method_descriptor->input_type()->name();
const std::string& response_type_name = method_descriptor->output_type()->name();

std::string request_type_descriptor;
std::string response_type_descriptor;

dyn_decoder.GetServiceMessageDescFromType(service_descriptor, request_type_name, request_type_descriptor, error_s);
dyn_decoder.GetServiceMessageDescFromType(service_descriptor, response_type_name, response_type_descriptor, error_s);

method_information_map.emplace(SServiceMethodInformation{
method_name,
SDataTypeInformation{request_type_name, "proto", request_type_descriptor},
SDataTypeInformation{response_type_name, "proto", response_type_descriptor}
});
}

return method_information_map;
}
};
} // namespace protobuf
} // namespace eCAL
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/* ========================= eCAL LICENSE =================================
*
* Copyright (C) 2016 - 2025 Continental Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ========================= eCAL LICENSE =================================
*/

/**
* @file client_protobuf_utils.h
* @brief eCAL client protobuf service utility functions
**/

#pragma once

#include <ecal/service/client.h>
#include <ecal/msg/protobuf/ecal_proto_dyn.h>

#include <google/protobuf/service.h>
#include <google/protobuf/descriptor.h>

#include <stdexcept>
#include <string>

namespace eCAL
{
namespace protobuf
{
/**
* @brief Retrieves the full service name from the Protobuf descriptor of the given type T.
*
* The service type T is expected to be generated by Protobuf and have
* a static method_descriptor or a protected GetDescriptor() method.
*
* @tparam T The Protobuf-generated service class.
*
* @return The full service name (e.g. "myproto.MyService").
*/
template <typename T>
std::string GetServiceNameFromDescriptor()
{
struct U : T {}; // Temporary subclass to access protected GetDescriptor()
U temp_instance;
return temp_instance.GetDescriptor()->full_name();
}

/**
* @brief Creates a ServiceMethodInformationSetT for all methods in service type T,
* so that eCAL knows how to serialize/deserialize them (proto).
*
* @tparam T The Protobuf-generated service class.
* @return The set of method info for eCAL registration.
*/
template <typename T>
eCAL::ServiceMethodInformationSetT CreateServiceMethodInformationSet()
{
struct U : T {}; // Temporary subclass to access protected GetDescriptor()
U temp_instance;
const google::protobuf::ServiceDescriptor* service_descriptor = temp_instance.GetDescriptor();

if (service_descriptor == nullptr)
{
throw std::runtime_error("Failed to retrieve service descriptor.");
}

ServiceMethodInformationSetT method_information_set;
CProtoDynDecoder dyn_decoder;
std::string error_s;

for (int i = 0; i < service_descriptor->method_count(); ++i)
{
const google::protobuf::MethodDescriptor* method_descriptor = service_descriptor->method(i);
const std::string& method_name = method_descriptor->name();

const std::string& request_type_name = method_descriptor->input_type()->name();
const std::string& response_type_name = method_descriptor->output_type()->name();

std::string request_type_descriptor;
std::string response_type_descriptor;

dyn_decoder.GetServiceMessageDescFromType(service_descriptor, request_type_name, request_type_descriptor, error_s);
dyn_decoder.GetServiceMessageDescFromType(service_descriptor, response_type_name, response_type_descriptor, error_s);

method_information_set.emplace(SServiceMethodInformation{
method_name,
SDataTypeInformation{request_type_name, "proto", request_type_descriptor},
SDataTypeInformation{response_type_name, "proto", response_type_descriptor}
});
}

return method_information_set;
}
} // namespace protobuf
} // namespace eCAL
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* @file client_response_parser.h
* @brief eCAL client response message parser
**/

#include <ecal/service/types.h>
#include <ecal/msg/protobuf/client_typed_response.h>

Expand Down

0 comments on commit 7ff7b07

Please sign in to comment.