• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
9 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
10 
11 #include <cstddef>
12 #include <functional>
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 #include "absl/container/flat_hash_map.h"
18 #include "absl/container/flat_hash_set.h"
19 #include "google/protobuf/compiler/objectivec/enum.h"
20 #include "google/protobuf/compiler/objectivec/extension.h"
21 #include "google/protobuf/compiler/objectivec/message.h"
22 #include "google/protobuf/compiler/objectivec/options.h"
23 #include "google/protobuf/descriptor.h"
24 #include "google/protobuf/io/printer.h"
25 
26 namespace google {
27 namespace protobuf {
28 namespace compiler {
29 namespace objectivec {
30 
31 class FileGenerator {
32  public:
33   // Wrapper for some common state that is shared between file generations to
34   // improve performance when more than one file is generated at a time.
35   struct CommonState {
36     // `include_custom_options` will cause any custom options to be included
37     // in the calculations around files defining extensions.
CommonStateCommonState38     explicit CommonState(bool include_custom_options)
39         : include_custom_options(include_custom_options) {}
40 
41     std::vector<const FileDescriptor*>
42     CollectMinimalFileDepsContainingExtensions(const FileDescriptor* file);
43 
44    private:
45     struct MinDepsEntry {
46       bool has_extensions;
47       // The minimal dependencies that cover all the dependencies with
48       // extensions.
49       absl::flat_hash_set<const FileDescriptor*> min_deps;
50       absl::flat_hash_set<const FileDescriptor*> transitive_deps;
51     };
52     const MinDepsEntry& CollectMinimalFileDepsContainingExtensionsInternal(
53         const FileDescriptor* file);
54     absl::flat_hash_map<const FileDescriptor*, MinDepsEntry> deps_info_cache;
55     const bool include_custom_options;
56   };
57 
58   FileGenerator(Edition edition, const FileDescriptor* file,
59                 const GenerationOptions& generation_options,
60                 CommonState& common_state);
61   ~FileGenerator() = default;
62 
63   FileGenerator(const FileGenerator&) = delete;
64   FileGenerator& operator=(const FileGenerator&) = delete;
65 
66   void GenerateHeader(io::Printer* p) const;
67   void GenerateSource(io::Printer* p) const;
68 
NumEnums()69   int NumEnums() const { return enum_generators_.size(); }
NumMessages()70   int NumMessages() const { return message_generators_.size(); }
71 
72   void GenerateGlobalSource(io::Printer* p) const;
73   void GenerateSourceForMessage(int idx, io::Printer* p) const;
74   void GenerateSourceForEnums(io::Printer* p) const;
75 
76  private:
77   enum class GeneratedFileType : int { kHeader, kSource };
78   struct GeneratedFileOptions {
79     std::vector<std::string> ignored_warnings;
80     std::vector<const FileDescriptor*> forced_files_to_import;
81     std::vector<std::string> extra_system_headers;
82   };
83 
84   void GenerateFile(io::Printer* p, GeneratedFileType file_type,
85                     const GeneratedFileOptions& file_options,
86                     std::function<void()> body) const;
GenerateFile(io::Printer * p,GeneratedFileType file_type,std::function<void ()> body)87   void GenerateFile(io::Printer* p, GeneratedFileType file_type,
88                     std::function<void()> body) const {
89     GeneratedFileOptions file_options;
90     GenerateFile(p, file_type, file_options, body);
91   }
92 
93   void EmitRootImplementation(
94       io::Printer* p,
95       const std::vector<const FileDescriptor*>& deps_with_extensions) const;
96   void EmitRootExtensionRegistryImplementation(
97       io::Printer* p,
98       const std::vector<const FileDescriptor*>& deps_with_extensions) const;
99   void EmitFileDescription(io::Printer* p) const;
100 
101   enum class PublicDepsHandling : int {
102     kAsUsed,        // No special handing, require references to import then.
103     kForceInclude,  // Always treat them as needed.
104     kExclude,       // Never treat them as needed.
105   };
106   // `public_deps_handling` controls how the public imports in this file should
107   // be handed.
108   void DetermineNeededDeps(absl::flat_hash_set<const FileDescriptor*>* deps,
109                            PublicDepsHandling public_deps_handling) const;
110 
HeadersUseForwardDeclarations()111   bool HeadersUseForwardDeclarations() const {
112     // The bundled protos (WKTs) don't make use of forward declarations.
113     return !is_bundled_proto_ &&
114            generation_options_.headers_use_forward_declarations;
115   }
116 
117   const Edition edition_;
118   const FileDescriptor* file_;
119   const GenerationOptions& generation_options_;
120   mutable CommonState* common_state_;
121   const std::string root_class_name_;
122   const std::string file_description_name_;
123   const bool is_bundled_proto_;
124 
125   std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
126   std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
127   // The first file_scoped_extension_count_ are the extensions at file level
128   // scope. This can be less than file_->extension_count() when custom options
129   // are being filtered away.
130   size_t file_scoped_extension_count_;
131   std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
132 };
133 
134 }  // namespace objectivec
135 }  // namespace compiler
136 }  // namespace protobuf
137 }  // namespace google
138 
139 #endif  // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
140