Clarify same-crate-import vs different-crate-import message fields (latter unsupported).

PiperOrigin-RevId: 579175657
pull/14613/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent 4721f6a5e9
commit 6ee7a322d3
  1. 15
      src/google/protobuf/compiler/rust/accessors/accessors.cc
  2. 9
      src/google/protobuf/compiler/rust/accessors/singular_message.cc
  3. 43
      src/google/protobuf/compiler/rust/context.h
  4. 23
      src/google/protobuf/compiler/rust/generator.cc

@ -23,7 +23,8 @@ namespace rust {
namespace {
std::unique_ptr<AccessorGenerator> AccessorGeneratorFor(
const FieldDescriptor& desc) {
Context<FieldDescriptor> field) {
const FieldDescriptor& desc = field.desc();
// TODO: We do not support [ctype=FOO] (used to set the field
// type in C++ to cord or string_piece) in V0.6 API.
if (desc.options().has_ctype()) {
@ -59,6 +60,12 @@ std::unique_ptr<AccessorGenerator> AccessorGeneratorFor(
if (desc.is_repeated()) {
return std::make_unique<UnsupportedField>("repeated msg not supported");
}
if (!field.generator_context().is_file_in_current_crate(
desc.message_type()->file())) {
return std::make_unique<UnsupportedField>(
"message fields that are imported from another proto_library"
" (defined in a separate Rust crate) are not supported");
}
return std::make_unique<SingularMessage>();
case FieldDescriptor::TYPE_ENUM:
@ -74,15 +81,15 @@ std::unique_ptr<AccessorGenerator> AccessorGeneratorFor(
} // namespace
void GenerateAccessorMsgImpl(Context<FieldDescriptor> field) {
AccessorGeneratorFor(field.desc())->GenerateMsgImpl(field);
AccessorGeneratorFor(field)->GenerateMsgImpl(field);
}
void GenerateAccessorExternC(Context<FieldDescriptor> field) {
AccessorGeneratorFor(field.desc())->GenerateExternC(field);
AccessorGeneratorFor(field)->GenerateExternC(field);
}
void GenerateAccessorThunkCc(Context<FieldDescriptor> field) {
AccessorGeneratorFor(field.desc())->GenerateThunkCc(field);
AccessorGeneratorFor(field)->GenerateThunkCc(field);
}
} // namespace rust

@ -5,7 +5,6 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/compiler/rust/accessors/accessor_generator.h"
@ -20,13 +19,9 @@ namespace rust {
void SingularMessage::InMsgImpl(Context<FieldDescriptor> field) const {
Context<Descriptor> d = field.WithDesc(field.desc().message_type());
auto prefix = "crate::" + GetCrateRelativeQualifiedPath(d);
// here we defer unit tests with messages that have import inside their
// pkg name e.g. unittest_import.proto
if (absl::StrContains(prefix, "import")) {
// TODO: Handle imports correctly, default to $Msg$View for now
prefix = field.desc().containing_type()->name();
}
if (field.is_cpp()) {
field.Emit({{"prefix", prefix},
{"field", field.desc().name()},

@ -8,10 +8,14 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_RUST_CONTEXT_H__
#define GOOGLE_PROTOBUF_COMPILER_RUST_CONTEXT_H__
#include <algorithm>
#include <vector>
#include "absl/log/absl_log.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/io/printer.h"
namespace google {
@ -43,6 +47,26 @@ struct Options {
static absl::StatusOr<Options> Parse(absl::string_view param);
};
class RustGeneratorContext {
public:
explicit RustGeneratorContext(
const std::vector<const FileDescriptor*>* files_in_current_crate)
: files_in_current_crate_(*files_in_current_crate) {}
const FileDescriptor* primary_file() const {
return files_in_current_crate_.front();
}
bool is_file_in_current_crate(const FileDescriptor* f) const {
return std::find(files_in_current_crate_.begin(),
files_in_current_crate_.end(),
f) != files_in_current_crate_.end();
}
private:
const std::vector<const FileDescriptor*>& files_in_current_crate_;
};
// A context for generating a particular kind of definition.
// This type acts as an options struct (as in go/totw/173) for most of the
// generator.
@ -52,14 +76,22 @@ struct Options {
template <typename Descriptor>
class Context {
public:
Context(const Options* opts, const Descriptor* desc, io::Printer* printer)
: opts_(opts), desc_(desc), printer_(printer) {}
Context(const Options* opts, const Descriptor* desc,
const RustGeneratorContext* rust_generator_context,
io::Printer* printer)
: opts_(opts),
desc_(desc),
rust_generator_context_(rust_generator_context),
printer_(printer) {}
Context(const Context&) = default;
Context& operator=(const Context&) = default;
const Descriptor& desc() const { return *desc_; }
const Options& opts() const { return *opts_; }
const RustGeneratorContext& generator_context() const {
return *rust_generator_context_;
}
bool is_cpp() const { return opts_->kernel == Kernel::kCpp; }
bool is_upb() const { return opts_->kernel == Kernel::kUpb; }
@ -70,16 +102,16 @@ class Context {
// Creates a new context over a different descriptor.
template <typename D>
Context<D> WithDesc(const D& desc) const {
return Context<D>(opts_, &desc, printer_);
return Context<D>(opts_, &desc, rust_generator_context_, printer_);
}
template <typename D>
Context<D> WithDesc(const D* desc) const {
return Context<D>(opts_, desc, printer_);
return Context<D>(opts_, desc, rust_generator_context_, printer_);
}
Context WithPrinter(io::Printer* printer) const {
return Context(opts_, desc_, printer);
return Context(opts_, desc_, rust_generator_context_, printer);
}
// Forwards to Emit(), which will likely be called all the time.
@ -97,6 +129,7 @@ class Context {
private:
const Options* opts_;
const Descriptor* desc_;
const RustGeneratorContext* rust_generator_context_;
io::Printer* printer_;
};
} // namespace rust

@ -123,11 +123,7 @@ void EmitPubUseForImportedMessages(Context<FileDescriptor>& primary_file,
}
// Emits all public imports of the current file
void EmitPublicImports(
Context<FileDescriptor>& primary_file,
const std::vector<const FileDescriptor*>& files_in_current_crate) {
absl::flat_hash_set<const FileDescriptor*> files(
files_in_current_crate.begin(), files_in_current_crate.end());
void EmitPublicImports(Context<FileDescriptor>& primary_file) {
for (int i = 0; i < primary_file.desc().public_dependency_count(); ++i) {
auto dep_file = primary_file.desc().public_dependency(i);
// If the publicly imported file is a src of the current `proto_library`
@ -137,7 +133,8 @@ void EmitPublicImports(
// TODO: Handle the case where a non-primary src with the same
// declared package as the primary src publicly imports a file that the
// primary doesn't.
if (files.contains(dep_file)) continue;
if (primary_file.generator_context().is_file_in_current_crate(dep_file))
continue;
auto dep = primary_file.WithDesc(dep_file);
EmitPubUseForImportedMessages(primary_file, dep);
}
@ -206,7 +203,13 @@ bool RustGenerator::Generate(const FileDescriptor* file_desc,
return false;
}
Context<FileDescriptor> file(&*opts, file_desc, nullptr);
std::vector<const FileDescriptor*> files_in_current_crate;
generator_context->ListParsedFiles(&files_in_current_crate);
RustGeneratorContext rust_generator_context(&files_in_current_crate);
Context<FileDescriptor> file(&*opts, file_desc, &rust_generator_context,
nullptr);
auto outfile = absl::WrapUnique(generator_context->Open(GetRsFile(file)));
io::Printer printer(outfile.get());
@ -228,15 +231,13 @@ bool RustGenerator::Generate(const FileDescriptor* file_desc,
)rs");
std::vector<const FileDescriptor*> files_in_current_crate;
generator_context->ListParsedFiles(&files_in_current_crate);
std::vector<Context<FileDescriptor>> file_contexts;
for (const FileDescriptor* f : files_in_current_crate) {
file_contexts.push_back(file.WithDesc(*f));
}
// Generating the primary file?
if (file_desc == files_in_current_crate.front()) {
if (file_desc == rust_generator_context.primary_file()) {
auto non_primary_srcs = absl::MakeConstSpan(file_contexts).subspan(1);
DeclareSubmodulesForNonPrimarySrcs(file, non_primary_srcs);
@ -252,7 +253,7 @@ bool RustGenerator::Generate(const FileDescriptor* file_desc,
}
}
EmitPublicImports(file, files_in_current_crate);
EmitPublicImports(file);
std::unique_ptr<io::ZeroCopyOutputStream> thunks_cc;
std::unique_ptr<io::Printer> thunks_printer;

Loading…
Cancel
Save