PiperOrigin-RevId: 691208172pull/19030/head
parent
c4afb1974b
commit
bd3876189e
3 changed files with 177 additions and 0 deletions
@ -0,0 +1,98 @@ |
||||
// Copyright (c) 2024 Google LLC
|
||||
// All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#include "upb_generator/common/cpp_to_upb_def.h" |
||||
|
||||
#include <string> |
||||
|
||||
#include "google/protobuf/descriptor.upb.h" |
||||
#include "absl/log/absl_check.h" |
||||
#include "google/protobuf/descriptor.h" |
||||
#include "upb/base/status.hpp" |
||||
#include "upb/mem/arena.hpp" |
||||
#include "upb/mini_table/field.h" |
||||
#include "upb/reflection/def.hpp" |
||||
|
||||
namespace upb::generator { |
||||
|
||||
using google::protobuf::Descriptor; |
||||
using google::protobuf::EnumDescriptor; |
||||
using google::protobuf::FieldDescriptor; |
||||
using google::protobuf::FileDescriptor; |
||||
|
||||
// Internal helper that takes a filedesc and emits a upb proto;
|
||||
// used for defpool tracking and dependency management
|
||||
google_protobuf_FileDescriptorProto* ToUpbProto(const FileDescriptor* file, |
||||
upb::Arena* arena) { |
||||
google::protobuf::FileDescriptorProto proto; |
||||
file->CopyTo(&proto); |
||||
std::string serialized_proto = proto.SerializeAsString(); |
||||
google_protobuf_FileDescriptorProto* upb_proto = google_protobuf_FileDescriptorProto_parse( |
||||
serialized_proto.data(), serialized_proto.size(), arena->ptr()); |
||||
ABSL_CHECK(upb_proto) << "Failed to parse proto"; |
||||
return upb_proto; |
||||
} |
||||
|
||||
void AddFile(const FileDescriptor* file, upb::DefPool* pool) { |
||||
// Avoid adding the same file twice.
|
||||
if (pool->FindFileByName(file->name().c_str())) return; |
||||
|
||||
// Like a google::protobuf::DescriptorPool, a upb::DefPool requires that all
|
||||
// dependencies are added first.
|
||||
for (int i = 0; i < file->dependency_count(); i++) { |
||||
AddFile(file->dependency(i), pool); |
||||
} |
||||
|
||||
upb::Arena tmp_arena; |
||||
upb::Status status; |
||||
ABSL_CHECK(pool->AddFile(ToUpbProto(file, &tmp_arena), &status)) |
||||
<< status.error_message(); |
||||
} |
||||
|
||||
upb::MessageDefPtr FindMessageDef(upb::DefPool& pool, |
||||
const Descriptor* descriptor) { |
||||
const std::string& name = descriptor->full_name(); |
||||
upb::MessageDefPtr message_def = pool.FindMessageByName(name.c_str()); |
||||
ABSL_CHECK(message_def) << "No message named " << name; |
||||
return message_def; |
||||
} |
||||
|
||||
upb::EnumDefPtr FindEnumDef(upb::DefPool& pool, |
||||
const EnumDescriptor* enum_descriptor) { |
||||
const std::string& name = enum_descriptor->full_name(); |
||||
upb::EnumDefPtr enum_def = pool.FindEnumByName(name.c_str()); |
||||
ABSL_CHECK(enum_def) << "No enum named " << name; |
||||
return enum_def; |
||||
} |
||||
|
||||
upb::FieldDefPtr FindBaseFieldDef(upb::DefPool& pool, |
||||
const FieldDescriptor* field) { |
||||
ABSL_CHECK(!field->is_extension()); |
||||
upb::MessageDefPtr message_def = |
||||
FindMessageDef(pool, field->containing_type()); |
||||
upb::FieldDefPtr field_def = message_def.FindFieldByNumber(field->number()); |
||||
ABSL_CHECK(field_def) << "No field with number " << field->number() |
||||
<< " in message " << message_def.full_name(); |
||||
return field_def; |
||||
} |
||||
|
||||
upb::FieldDefPtr FindExtensionDef(upb::DefPool& pool, |
||||
const FieldDescriptor* field) { |
||||
ABSL_CHECK(field->is_extension()); |
||||
return pool.FindExtensionByName(field->full_name().c_str()); |
||||
} |
||||
|
||||
const FieldDescriptor* FindFieldDescriptor( |
||||
const Descriptor* message, const upb_MiniTableField* field_def) { |
||||
int field_number = upb_MiniTableField_Number(field_def); |
||||
const FieldDescriptor* field = message->FindFieldByNumber(field_number); |
||||
ABSL_CHECK(field) << "No field in message " << message->full_name() |
||||
<< " with number " << field_number; |
||||
return field; |
||||
} |
||||
|
||||
} // namespace upb::generator
|
@ -0,0 +1,58 @@ |
||||
// Copyright (c) 2024 Google LLC
|
||||
// All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#ifndef THIRD_PARTY_UPB_UPB_GENERATOR_COMMON_DESC_HELPERS_H_ |
||||
#define THIRD_PARTY_UPB_UPB_GENERATOR_COMMON_DESC_HELPERS_H_ |
||||
|
||||
#include "google/protobuf/descriptor.pb.h" |
||||
#include "google/protobuf/descriptor.upb.h" |
||||
#include "google/protobuf/descriptor.h" |
||||
#include "upb/mem/arena.hpp" |
||||
#include "upb/mini_table/field.h" |
||||
#include "upb/reflection/def.hpp" |
||||
|
||||
namespace upb::generator { |
||||
|
||||
using google::protobuf::Descriptor; |
||||
using google::protobuf::EnumDescriptor; |
||||
using google::protobuf::FieldDescriptor; |
||||
using google::protobuf::FileDescriptor; |
||||
|
||||
// Add a filedesc to defpool, and all its dependencies.
|
||||
void AddFile(const FileDescriptor* file, upb::DefPool* pool); |
||||
|
||||
// Given a Descriptor, returns a MessageDefPtr.
|
||||
// This will fail if the message is not in the defpool.
|
||||
// Files can be added to the defpool using AddFile.
|
||||
upb::MessageDefPtr FindMessageDef(upb::DefPool& pool, |
||||
const Descriptor* descriptor); |
||||
|
||||
// Given an EnumDescriptor, returns an EnumDefPtr.
|
||||
// This will fail if the enum is not in the defpool.
|
||||
upb::EnumDefPtr FindEnumDef(upb::DefPool& pool, |
||||
const EnumDescriptor* enum_descriptor); |
||||
|
||||
// Given a FieldDescriptor, returns a FieldDefPtr.
|
||||
// This will fail if the field is not in the defpool.
|
||||
// This is for non-extension fields. For extensions, use FindExtensionDef.
|
||||
upb::FieldDefPtr FindBaseFieldDef(upb::DefPool& pool, |
||||
const FieldDescriptor* field); |
||||
|
||||
// Given a FieldDescriptor, returns a FieldDefPtr.
|
||||
// This will fail if the field is not in the defpool.
|
||||
// This is solely for extension fields.
|
||||
upb::FieldDefPtr FindExtensionDef(upb::DefPool& pool, |
||||
const FieldDescriptor* field); |
||||
|
||||
// Looks up a FieldDescriptor from a upb_MiniTableField.
|
||||
// This will fail if the field is not in the message.
|
||||
const FieldDescriptor* FindFieldDescriptor(const Descriptor* message, |
||||
const upb_MiniTableField* field_def); |
||||
|
||||
} // namespace upb::generator
|
||||
|
||||
#endif // THIRD_PARTY_UPB_UPB_GENERATOR_COMMON_DESC_HELPERS_H_
|
Loading…
Reference in new issue