Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:00

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2023 Google LLC.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 #ifndef GOOGLE_PROTOBUF_COMPILER_RUST_CONTEXT_H__
0009 #define GOOGLE_PROTOBUF_COMPILER_RUST_CONTEXT_H__
0010 
0011 #include <algorithm>
0012 #include <string>
0013 #include <vector>
0014 
0015 #include "absl/container/flat_hash_map.h"
0016 #include "absl/log/absl_log.h"
0017 #include "absl/status/statusor.h"
0018 #include "absl/strings/string_view.h"
0019 #include "absl/types/span.h"
0020 #include "google/protobuf/descriptor.h"
0021 #include "google/protobuf/io/printer.h"
0022 
0023 namespace google {
0024 namespace protobuf {
0025 namespace compiler {
0026 namespace rust {
0027 // Marks which kernel the Rust codegen should generate code for.
0028 enum class Kernel {
0029   kUpb,
0030   kCpp,
0031 };
0032 
0033 inline absl::string_view KernelRsName(Kernel kernel) {
0034   switch (kernel) {
0035     case Kernel::kUpb:
0036       return "upb";
0037     case Kernel::kCpp:
0038       return "cpp";
0039     default:
0040       ABSL_LOG(FATAL) << "Unknown kernel type: " << static_cast<int>(kernel);
0041       return "";
0042   }
0043 }
0044 
0045 // Global options for a codegen invocation.
0046 struct Options {
0047   Kernel kernel;
0048   std::string mapping_file_path;
0049 
0050   static absl::StatusOr<Options> Parse(absl::string_view param);
0051 };
0052 
0053 class RustGeneratorContext {
0054  public:
0055   explicit RustGeneratorContext(
0056       const std::vector<const FileDescriptor*>* files_in_current_crate,
0057       const absl::flat_hash_map<std::string, std::string>*
0058           import_path_to_crate_name)
0059       : files_in_current_crate_(*files_in_current_crate),
0060         import_path_to_crate_name_(*import_path_to_crate_name) {}
0061 
0062   const FileDescriptor& primary_file() const {
0063     return *files_in_current_crate_.front();
0064   }
0065 
0066   bool is_file_in_current_crate(const FileDescriptor& f) const {
0067     return std::find(files_in_current_crate_.begin(),
0068                      files_in_current_crate_.end(),
0069                      &f) != files_in_current_crate_.end();
0070   }
0071 
0072   absl::string_view ImportPathToCrateName(absl::string_view import_path) const {
0073     auto it = import_path_to_crate_name_.find(import_path);
0074     if (it == import_path_to_crate_name_.end()) {
0075       ABSL_LOG(FATAL) << "Path " << import_path
0076                       << " not found in crate mapping. Crate mapping has "
0077                       << import_path_to_crate_name_.size() << " entries";
0078     }
0079     return it->second;
0080   }
0081 
0082  private:
0083   const std::vector<const FileDescriptor*>& files_in_current_crate_;
0084   const absl::flat_hash_map<std::string, std::string>&
0085       import_path_to_crate_name_;
0086 };
0087 
0088 // A context for generating a particular kind of definition.
0089 class Context {
0090  public:
0091   Context(const Options* opts,
0092           const RustGeneratorContext* rust_generator_context,
0093           io::Printer* printer)
0094       : opts_(opts),
0095         rust_generator_context_(rust_generator_context),
0096         printer_(printer) {}
0097 
0098   Context(const Context&) = delete;
0099   Context& operator=(const Context&) = delete;
0100   Context(Context&&) = default;
0101   Context& operator=(Context&&) = default;
0102 
0103   const Options& opts() const { return *opts_; }
0104   const RustGeneratorContext& generator_context() const {
0105     return *rust_generator_context_;
0106   }
0107 
0108   bool is_cpp() const { return opts_->kernel == Kernel::kCpp; }
0109   bool is_upb() const { return opts_->kernel == Kernel::kUpb; }
0110 
0111   // NOTE: prefer ctx.Emit() over ctx.printer().Emit();
0112   io::Printer& printer() const { return *printer_; }
0113 
0114   Context WithPrinter(io::Printer* printer) const {
0115     return Context(opts_, rust_generator_context_, printer);
0116   }
0117 
0118   // Forwards to Emit(), which will likely be called all the time.
0119   void Emit(absl::string_view format,
0120             io::Printer::SourceLocation loc =
0121                 io::Printer::SourceLocation::current()) const {
0122     printer_->Emit(format, loc);
0123   }
0124   void Emit(absl::Span<const io::Printer::Sub> vars, absl::string_view format,
0125             io::Printer::SourceLocation loc =
0126                 io::Printer::SourceLocation::current()) const {
0127     printer_->Emit(vars, format, loc);
0128   }
0129 
0130  private:
0131   const Options* opts_;
0132   const RustGeneratorContext* rust_generator_context_;
0133   io::Printer* printer_;
0134 };
0135 
0136 bool IsInCurrentlyGeneratingCrate(Context& ctx, const FileDescriptor& file);
0137 bool IsInCurrentlyGeneratingCrate(Context& ctx, const Descriptor& message);
0138 bool IsInCurrentlyGeneratingCrate(Context& ctx, const EnumDescriptor& enum_);
0139 
0140 }  // namespace rust
0141 }  // namespace compiler
0142 }  // namespace protobuf
0143 }  // namespace google
0144 
0145 #endif  // GOOGLE_PROTOBUF_COMPILER_RUST_CONTEXT_H__