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