Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:11:56

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  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 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 
0012 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
0013 #define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
0014 
0015 #include <functional>
0016 #include <memory>
0017 #include <string>
0018 #include <vector>
0019 
0020 #include "absl/container/flat_hash_map.h"
0021 #include "absl/container/flat_hash_set.h"
0022 #include "absl/functional/any_invocable.h"
0023 #include "absl/log/absl_check.h"
0024 #include "google/protobuf/compiler/cpp/enum.h"
0025 #include "google/protobuf/compiler/cpp/extension.h"
0026 #include "google/protobuf/compiler/cpp/helpers.h"
0027 #include "google/protobuf/compiler/cpp/message.h"
0028 #include "google/protobuf/compiler/cpp/options.h"
0029 #include "google/protobuf/compiler/cpp/service.h"
0030 #include "google/protobuf/compiler/scc.h"
0031 #include "google/protobuf/descriptor.h"
0032 #include "google/protobuf/io/printer.h"
0033 
0034 // Must be included last.
0035 #include "google/protobuf/port_def.inc"
0036 
0037 namespace google {
0038 namespace protobuf {
0039 namespace compiler {
0040 namespace cpp {
0041 class PROTOC_EXPORT FileGenerator {
0042  public:
0043   FileGenerator(const FileDescriptor* file, const Options& options);
0044 
0045   FileGenerator(const FileGenerator&) = delete;
0046   FileGenerator& operator=(const FileGenerator&) = delete;
0047 
0048   ~FileGenerator() = default;
0049 
0050   // info_path, if non-empty, should be the path (relative to printer's
0051   // output) to the metadata file describing this proto header.
0052   void GenerateProtoHeader(io::Printer* p, absl::string_view info_path);
0053   // info_path, if non-empty, should be the path (relative to printer's
0054   // output) to the metadata file describing this PB header.
0055   void GeneratePBHeader(io::Printer* p, absl::string_view info_path);
0056   void GenerateSource(io::Printer* p);
0057 
0058   // The following member functions are used when the lite_implicit_weak_fields
0059   // option is set. In this mode the code is organized a bit differently to
0060   // promote better linker stripping of unused code. In particular, we generate
0061   // one .cc file per message, one .cc file per extension, and a main pb.cc file
0062   // containing everything else.
0063 
0064   int NumMessages() const { return message_generators_.size(); }
0065   int NumExtensions() const { return extension_generators_.size(); }
0066   // Generates the source file for one message.
0067   void GenerateSourceForMessage(int idx, io::Printer* p);
0068   // Generates the source file for one extension.
0069   void GenerateSourceForExtension(int idx, io::Printer* p);
0070   // Generates a source file containing everything except messages and
0071   // extensions.
0072   void GenerateGlobalSource(io::Printer* p);
0073 
0074  private:
0075   // Generates a file, setting up the necessary accoutrements that start and
0076   // end the file, calling `cb` in between.
0077   //
0078   // This includes header guards and file-global variables.
0079   void GenerateFile(io::Printer* p, GeneratedFileType file_type,
0080                     std::function<void()> cb);
0081 
0082   // Generates a static initializers with all the existing values from
0083   // `static_initializers_`.
0084   // They run in `PROTOBUF_ATTRIBUTE_INIT_PRIORITY1` and
0085   // `PROTOBUF_ATTRIBUTE_INIT_PRIORITY2` priority respectively.
0086   void GenerateStaticInitializer(io::Printer* p);
0087 
0088   // Shared code between the two header generators.
0089   void GenerateSharedHeaderCode(io::Printer* p);
0090 
0091   // Internal type used by GenerateForwardDeclarations (defined in file.cc).
0092   class ForwardDeclarations;
0093   struct CrossFileReferences;
0094 
0095   void IncludeFile(absl::string_view google3_name, io::Printer* p) {
0096     DoIncludeFile(google3_name, false, p);
0097   }
0098   void IncludeFileAndExport(absl::string_view google3_name, io::Printer* p) {
0099     DoIncludeFile(google3_name, true, p);
0100   }
0101   void DoIncludeFile(absl::string_view google3_name, bool do_export,
0102                      io::Printer* p);
0103 
0104   std::string CreateHeaderInclude(absl::string_view basename,
0105                                   const FileDescriptor* file);
0106   void GetCrossFileReferencesForField(const FieldDescriptor* field,
0107                                       CrossFileReferences* refs);
0108   void GetCrossFileReferencesForFile(const FileDescriptor* file,
0109                                      CrossFileReferences* refs);
0110   void GenerateInternalForwardDeclarations(const CrossFileReferences& refs,
0111                                            io::Printer* p);
0112   void GenerateSourceIncludes(io::Printer* p);
0113   void GenerateSourcePrelude(io::Printer* p);
0114   void GenerateSourceDefaultInstance(int idx, io::Printer* p);
0115 
0116   void GenerateInitForSCC(const SCC* scc, const CrossFileReferences& refs,
0117                           io::Printer* p);
0118   void GenerateReflectionInitializationCode(io::Printer* p);
0119 
0120   // For other imports, generates their forward-declarations.
0121   void GenerateForwardDeclarations(io::Printer* p);
0122 
0123   // Generates top or bottom of a header file.
0124   void GenerateTopHeaderGuard(io::Printer* p, GeneratedFileType file_type);
0125   void GenerateBottomHeaderGuard(io::Printer* p, GeneratedFileType file_type);
0126 
0127   // Generates #include directives.
0128   void GenerateLibraryIncludes(io::Printer* p);
0129   void GenerateDependencyIncludes(io::Printer* p);
0130 
0131   // Generate a pragma to pull in metadata using the given info_path (if
0132   // non-empty). info_path should be relative to printer's output.
0133   void GenerateMetadataPragma(io::Printer* p, absl::string_view info_path);
0134 
0135   // Generates a couple of different pieces before definitions:
0136   void GenerateGlobalStateFunctionDeclarations(io::Printer* p);
0137 
0138   // Generates types for classes.
0139   void GenerateMessageDefinitions(io::Printer* p);
0140 
0141   void GenerateEnumDefinitions(io::Printer* p);
0142 
0143   // Generates generic service definitions.
0144   void GenerateServiceDefinitions(io::Printer* p);
0145 
0146   // Generates extension identifiers.
0147   void GenerateExtensionIdentifiers(io::Printer* p);
0148 
0149   // Generates inline function definitions.
0150   void GenerateInlineFunctionDefinitions(io::Printer* p);
0151 
0152   void GenerateProto2NamespaceEnumSpecializations(io::Printer* p);
0153 
0154   // Sometimes the names we use in a .proto file happen to be defined as
0155   // macros on some platforms (e.g., macro/minor used in plugin.proto are
0156   // defined as macros in sys/types.h on FreeBSD and a few other platforms).
0157   // To make the generated code compile on these platforms, we either have to
0158   // undef the macro for these few platforms, or rename the field name for all
0159   // platforms. Since these names are part of protobuf public API, renaming is
0160   // generally a breaking change so we prefer the #undef approach.
0161   void GenerateMacroUndefs(io::Printer* p);
0162 
0163   // Calculates if we should skip importing a specific dependency.
0164   bool ShouldSkipDependencyImports(const FileDescriptor* dep) const;
0165 
0166   bool IsDepWeak(const FileDescriptor* dep) const {
0167     if (weak_deps_.count(dep) != 0) {
0168       ABSL_CHECK(!options_.opensource_runtime);
0169       return true;
0170     }
0171     return false;
0172   }
0173 
0174   // For testing only.  Returns the descriptors ordered topologically.
0175   std::vector<const Descriptor*> MessagesInTopologicalOrder() const;
0176   friend class FileGeneratorFriendForTesting;
0177 
0178   absl::flat_hash_set<const FileDescriptor*> weak_deps_;
0179 
0180   std::vector<absl::AnyInvocable<void(io::Printer*)>> static_initializers_[2];
0181 
0182   const FileDescriptor* file_;
0183   Options options_;
0184 
0185   MessageSCCAnalyzer scc_analyzer_;
0186 
0187   // This member is unused and should be deleted once all old-style variable
0188   // maps are gone.
0189   // TODO
0190   absl::flat_hash_map<absl::string_view, std::string> variables_;
0191 
0192   // Contains the post-order walk of all the messages (and nested messages)
0193   // defined in this file. If you need a pre-order walk just reverse iterate.
0194   std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
0195   std::vector<int> message_generators_topologically_ordered_;
0196   std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
0197   std::vector<std::unique_ptr<ServiceGenerator>> service_generators_;
0198   std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
0199 };
0200 
0201 }  // namespace cpp
0202 }  // namespace compiler
0203 }  // namespace protobuf
0204 }  // namespace google
0205 
0206 #include "google/protobuf/port_undef.inc"
0207 
0208 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__