Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ cc_library(
],
deps = [
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_protobuf//:protobuf",
],
)
7 changes: 1 addition & 6 deletions src/include/grpc_transcoding/type_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,10 @@ namespace grpc {

namespace transcoding {

class SimpleTypeResolver;

// Provides ::google::protobuf::util::TypeResolver and
// ::google::protobuf::util::converter::TypeInfo implementations based on a
// collection of types and a collection of enums.
// This object is thread-safe
class TypeHelper {
public:
template <typename Types, typename Enums>
Expand Down Expand Up @@ -76,10 +75,6 @@ class TypeHelper {
void AddType(const ::google::protobuf::Type& t);
void AddEnum(const ::google::protobuf::Enum& e);

// We can't use a unique_ptr<SimpleTypeResolver> as the default deleter of
// unique_ptr requires the type to be defined when the unique_ptr destructor
// is called. In our case it's called from the template constructor below
// (most likely as a part of stack unwinding when an exception occurs).
::google::protobuf::util::TypeResolver* type_resolver_;
std::unique_ptr<::google::protobuf::util::converter::TypeInfo> type_info_;

Expand Down
51 changes: 45 additions & 6 deletions src/type_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,23 @@
//
#include "grpc_transcoding/type_helper.h"

#include "absl/strings/str_split.h"
#include <string>
#include <unordered_map>

#include "absl/strings/str_split.h"
#include "absl/synchronization/mutex.h"
#include "google/protobuf/type.pb.h"
#include "google/protobuf/util/internal/type_info.h"
#include "google/protobuf/util/type_resolver.h"

#include <string>
#include <unordered_map>

namespace pbutil = ::google::protobuf::util;
namespace pbconv = ::google::protobuf::util::converter;

namespace google {
namespace grpc {

namespace transcoding {
namespace {

const char DEFAULT_URL_PREFIX[] = "type.googleapis.com/";

Expand Down Expand Up @@ -108,9 +109,46 @@ class SimpleTypeResolver : public pbutil::TypeResolver {
SimpleTypeResolver& operator=(const SimpleTypeResolver&) = delete;
};

class LockedTypeInfo : public pbconv::TypeInfo {
public:
LockedTypeInfo(pbconv::TypeInfo* type_info) : type_info_(type_info) {}

pbutil::StatusOr<const google::protobuf::Type*> ResolveTypeUrl(
google::protobuf::StringPiece type_url) const override {
absl::MutexLock lock(&mutex_);
return type_info_->ResolveTypeUrl(type_url);
}

const google::protobuf::Type* GetTypeByTypeUrl(
google::protobuf::StringPiece type_url) const override {
absl::MutexLock lock(&mutex_);
return type_info_->GetTypeByTypeUrl(type_url);
}

const google::protobuf::Enum* GetEnumByTypeUrl(
google::protobuf::StringPiece type_url) const override {
absl::MutexLock lock(&mutex_);
return type_info_->GetEnumByTypeUrl(type_url);
}

const google::protobuf::Field* FindField(
const google::protobuf::Type* type,
google::protobuf::StringPiece camel_case_name) const override {
absl::MutexLock lock(&mutex_);
return type_info_->FindField(type, camel_case_name);
}

private:
mutable absl::Mutex mutex_;
std::unique_ptr<pbconv::TypeInfo> type_info_ ABSL_GUARDED_BY(mutex_);
};

} // namespace

TypeHelper::TypeHelper(pbutil::TypeResolver* type_resolver)
: type_resolver_(type_resolver),
type_info_(pbconv::TypeInfo::NewTypeInfo(type_resolver)) {}
type_info_(
new LockedTypeInfo(pbconv::TypeInfo::NewTypeInfo(type_resolver))) {}

TypeHelper::~TypeHelper() {
type_info_.reset();
Expand All @@ -123,7 +161,8 @@ pbconv::TypeInfo* TypeHelper::Info() const { return type_info_.get(); }

void TypeHelper::Initialize() {
type_resolver_ = new SimpleTypeResolver();
type_info_.reset(pbconv::TypeInfo::NewTypeInfo(type_resolver_));
type_info_.reset(
new LockedTypeInfo(pbconv::TypeInfo::NewTypeInfo(type_resolver_)));
}

void TypeHelper::AddType(const google::protobuf::Type& t) {
Expand Down