• 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 // Author: kenton@google.com (Kenton Varda)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 
12 #include "google/protobuf/compiler/code_generator.h"
13 
14 #include <cstddef>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "absl/log/absl_log.h"
20 #include "absl/status/statusor.h"
21 #include "absl/strings/match.h"
22 #include "absl/strings/str_cat.h"
23 #include "absl/strings/str_split.h"
24 #include "absl/strings/string_view.h"
25 #include "absl/strings/strip.h"
26 #include "google/protobuf/compiler/plugin.pb.h"
27 #include "google/protobuf/descriptor.h"
28 #include "google/protobuf/feature_resolver.h"
29 
30 // Must be included last.
31 #include "google/protobuf/port_def.inc"
32 
33 namespace google {
34 namespace protobuf {
35 namespace compiler {
36 
37 CodeGenerator::~CodeGenerator() = default;
38 
GenerateAll(const std::vector<const FileDescriptor * > & files,const std::string & parameter,GeneratorContext * generator_context,std::string * error) const39 bool CodeGenerator::GenerateAll(const std::vector<const FileDescriptor*>& files,
40                                 const std::string& parameter,
41                                 GeneratorContext* generator_context,
42                                 std::string* error) const {
43   // Default implementation is just to call the per file method, and prefix any
44   // error string with the file to provide context.
45   bool succeeded = true;
46   for (size_t i = 0; i < files.size(); i++) {
47     const FileDescriptor* file = files[i];
48     succeeded = Generate(file, parameter, generator_context, error);
49     if (!succeeded && error && error->empty()) {
50       *error =
51           "Code generator returned false but provided no error "
52           "description.";
53     }
54     if (error && !error->empty()) {
55       *error = absl::StrCat(file->name(), ": ", *error);
56       break;
57     }
58     if (!succeeded) {
59       break;
60     }
61   }
62   return succeeded;
63 }
64 
BuildFeatureSetDefaults() const65 absl::StatusOr<FeatureSetDefaults> CodeGenerator::BuildFeatureSetDefaults()
66     const {
67   if ((GetSupportedFeatures() & FEATURE_SUPPORTS_EDITIONS) == 0) {
68     // For generators that don't fully support editions yet, provide an
69     // optimistic set of defaults.  Protoc will check this condition later
70     // anyway.
71     return FeatureResolver::CompileDefaults(
72         FeatureSet::descriptor(), GetFeatureExtensions(),
73         MinimumAllowedEdition(), MaximumAllowedEdition());
74   }
75   return FeatureResolver::CompileDefaults(
76       FeatureSet::descriptor(), GetFeatureExtensions(), GetMinimumEdition(),
77       GetMaximumEdition());
78 }
79 
80 GeneratorContext::~GeneratorContext() = default;
81 
OpenForAppend(const std::string & filename)82 io::ZeroCopyOutputStream* GeneratorContext::OpenForAppend(
83     const std::string& filename) {
84   return nullptr;
85 }
86 
OpenForInsert(const std::string & filename,const std::string & insertion_point)87 io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert(
88     const std::string& filename, const std::string& insertion_point) {
89   ABSL_LOG(FATAL) << "This GeneratorContext does not support insertion.";
90   return nullptr;  // make compiler happy
91 }
92 
OpenForInsertWithGeneratedCodeInfo(const std::string & filename,const std::string & insertion_point,const google::protobuf::GeneratedCodeInfo &)93 io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo(
94     const std::string& filename, const std::string& insertion_point,
95     const google::protobuf::GeneratedCodeInfo& /*info*/) {
96   return OpenForInsert(filename, insertion_point);
97 }
98 
ListParsedFiles(std::vector<const FileDescriptor * > * output)99 void GeneratorContext::ListParsedFiles(
100     std::vector<const FileDescriptor*>* output) {
101   ABSL_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
102 }
103 
GetCompilerVersion(Version * version) const104 void GeneratorContext::GetCompilerVersion(Version* version) const {
105   version->set_major(GOOGLE_PROTOBUF_VERSION / 1000000);
106   version->set_minor(GOOGLE_PROTOBUF_VERSION / 1000 % 1000);
107   version->set_patch(GOOGLE_PROTOBUF_VERSION % 1000);
108   version->set_suffix(GOOGLE_PROTOBUF_VERSION_SUFFIX);
109 }
110 
CanSkipEditionCheck(absl::string_view filename)111 bool CanSkipEditionCheck(absl::string_view filename) {
112   return absl::StartsWith(filename, "google/protobuf/") ||
113          absl::StartsWith(filename, "upb/");
114 }
115 
116 }  // namespace compiler
117 }  // namespace protobuf
118 }  // namespace google
119 
120 #include "google/protobuf/port_undef.inc"
121