protobuf/src/google/protobuf/compiler/command_line_interface.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <google/protobuf/compiler/command_line_interface.h>
36 
37 #include <cstdint>
38 
39 #include <google/protobuf/stubs/platform_macros.h>
40 
41 #include <stdio.h>
42 #include <sys/types.h>
43 #ifdef major
44 #undef major
45 #endif
46 #ifdef minor
47 #undef minor
48 #endif
49 #include <fcntl.h>
50 #include <sys/stat.h>
51 #ifndef _MSC_VER
52 #include <unistd.h>
53 #endif
54 #include <ctype.h>
55 #include <errno.h>
56 #include <fstream>
57 #include <iostream>
58 
59 #include <limits.h> //For PATH_MAX
60 
61 #include <memory>
62 
63 #if defined(__APPLE__)
64 #include <mach-o/dyld.h>
65 #elif defined(__FreeBSD__)
66 #include <sys/sysctl.h>
67 #endif
68 
69 #include <google/protobuf/stubs/common.h>
70 #include <google/protobuf/stubs/logging.h>
71 #include <google/protobuf/stubs/stringprintf.h>
72 #include <google/protobuf/compiler/subprocess.h>
73 #include <google/protobuf/compiler/zip_writer.h>
74 #include <google/protobuf/compiler/plugin.pb.h>
75 #include <google/protobuf/compiler/code_generator.h>
76 #include <google/protobuf/compiler/importer.h>
77 #include <google/protobuf/io/coded_stream.h>
78 #include <google/protobuf/io/printer.h>
79 #include <google/protobuf/io/zero_copy_stream_impl.h>
80 #include <google/protobuf/descriptor.h>
81 #include <google/protobuf/dynamic_message.h>
82 #include <google/protobuf/text_format.h>
83 #include <google/protobuf/stubs/strutil.h>
84 #include <google/protobuf/stubs/substitute.h>
85 #include <google/protobuf/io/io_win32.h>
86 #include <google/protobuf/stubs/map_util.h>
87 #include <google/protobuf/stubs/stl_util.h>
88 
89 
90 #include <google/protobuf/port_def.inc>
91 
92 namespace google {
93 namespace protobuf {
94 namespace compiler {
95 
96 #ifndef O_BINARY
97 #ifdef _O_BINARY
98 #define O_BINARY _O_BINARY
99 #else
100 #define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
101 #endif
102 #endif
103 
104 namespace {
105 #if defined(_WIN32)
106 // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
107 // them like we do below.
108 using google::protobuf::io::win32::access;
110 using google::protobuf::io::win32::mkdir;
112 using google::protobuf::io::win32::setmode;
114 #endif
115 
116 static const char* kDefaultDirectDependenciesViolationMsg =
117  "File is imported but not declared in --direct_dependencies: %s";
118 
119 // Returns true if the text looks like a Windows-style absolute path, starting
120 // with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
121 // copy in importer.cc?
122 static bool IsWindowsAbsolutePath(const std::string& text) {
123 #if defined(_WIN32) || defined(__CYGWIN__)
124  return text.size() >= 3 && text[1] == ':' && isalpha(text[0]) &&
125  (text[2] == '/' || text[2] == '\\') && text.find_last_of(':') == 1;
126 #else
127  return false;
128 #endif
129 }
130 
131 void SetFdToTextMode(int fd) {
132 #ifdef _WIN32
133  if (setmode(fd, _O_TEXT) == -1) {
134  // This should never happen, I think.
135  GOOGLE_LOG(WARNING) << "setmode(" << fd << ", _O_TEXT): " << strerror(errno);
136  }
137 #endif
138  // (Text and binary are the same on non-Windows platforms.)
139 }
140 
141 void SetFdToBinaryMode(int fd) {
142 #ifdef _WIN32
143  if (setmode(fd, _O_BINARY) == -1) {
144  // This should never happen, I think.
145  GOOGLE_LOG(WARNING) << "setmode(" << fd << ", _O_BINARY): " << strerror(errno);
146  }
147 #endif
148  // (Text and binary are the same on non-Windows platforms.)
149 }
150 
151 void AddTrailingSlash(std::string* path) {
152  if (!path->empty() && path->at(path->size() - 1) != '/') {
153  path->push_back('/');
154  }
155 }
156 
157 bool VerifyDirectoryExists(const std::string& path) {
158  if (path.empty()) return true;
159 
160  if (access(path.c_str(), F_OK) == -1) {
161  std::cerr << path << ": " << strerror(errno) << std::endl;
162  return false;
163  } else {
164  return true;
165  }
166 }
167 
168 // Try to create the parent directory of the given file, creating the parent's
169 // parent if necessary, and so on. The full file name is actually
170 // (prefix + filename), but we assume |prefix| already exists and only create
171 // directories listed in |filename|.
172 bool TryCreateParentDirectory(const std::string& prefix,
173  const std::string& filename) {
174  // Recursively create parent directories to the output file.
175  // On Windows, both '/' and '\' are valid path separators.
176  std::vector<std::string> parts =
177  Split(filename, "/\\", true);
178  std::string path_so_far = prefix;
179  for (int i = 0; i < parts.size() - 1; i++) {
180  path_so_far += parts[i];
181  if (mkdir(path_so_far.c_str(), 0777) != 0) {
182  if (errno != EEXIST) {
183  std::cerr << filename << ": while trying to create directory "
184  << path_so_far << ": " << strerror(errno) << std::endl;
185  return false;
186  }
187  }
188  path_so_far += '/';
189  }
190 
191  return true;
192 }
193 
194 // Get the absolute path of this protoc binary.
195 bool GetProtocAbsolutePath(std::string* path) {
196 #ifdef _WIN32
197  char buffer[MAX_PATH];
198  int len = GetModuleFileNameA(NULL, buffer, MAX_PATH);
199 #elif defined(__APPLE__)
200  char buffer[PATH_MAX];
201  int len = 0;
202 
203  char dirtybuffer[PATH_MAX];
204  uint32_t size = sizeof(dirtybuffer);
205  if (_NSGetExecutablePath(dirtybuffer, &size) == 0) {
206  realpath(dirtybuffer, buffer);
207  len = strlen(buffer);
208  }
209 #elif defined(__FreeBSD__)
210  char buffer[PATH_MAX];
211  size_t len = PATH_MAX;
212  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
213  if (sysctl(mib, 4, &buffer, &len, NULL, 0) != 0) {
214  len = 0;
215  }
216 #else
217  char buffer[PATH_MAX];
218  int len = readlink("/proc/self/exe", buffer, PATH_MAX);
219 #endif
220  if (len > 0) {
221  path->assign(buffer, len);
222  return true;
223  } else {
224  return false;
225  }
226 }
227 
228 // Whether a path is where google/protobuf/descriptor.proto and other well-known
229 // type protos are installed.
230 bool IsInstalledProtoPath(const std::string& path) {
231  // Checking the descriptor.proto file should be good enough.
232  std::string file_path = path + "/google/protobuf/descriptor.proto";
233  return access(file_path.c_str(), F_OK) != -1;
234 }
235 
236 // Add the paths where google/protobuf/descriptor.proto and other well-known
237 // type protos are installed.
238 void AddDefaultProtoPaths(
239  std::vector<std::pair<std::string, std::string>>* paths) {
240  // TODO(xiaofeng): The code currently only checks relative paths of where
241  // the protoc binary is installed. We probably should make it handle more
242  // cases than that.
244  if (!GetProtocAbsolutePath(&path)) {
245  return;
246  }
247  // Strip the binary name.
248  size_t pos = path.find_last_of("/\\");
249  if (pos == std::string::npos || pos == 0) {
250  return;
251  }
252  path = path.substr(0, pos);
253  // Check the binary's directory.
254  if (IsInstalledProtoPath(path)) {
255  paths->push_back(std::pair<std::string, std::string>("", path));
256  return;
257  }
258  // Check if there is an include subdirectory.
259  if (IsInstalledProtoPath(path + "/include")) {
260  paths->push_back(
261  std::pair<std::string, std::string>("", path + "/include"));
262  return;
263  }
264  // Check if the upper level directory has an "include" subdirectory.
265  pos = path.find_last_of("/\\");
266  if (pos == std::string::npos || pos == 0) {
267  return;
268  }
269  path = path.substr(0, pos);
270  if (IsInstalledProtoPath(path + "/include")) {
271  paths->push_back(
272  std::pair<std::string, std::string>("", path + "/include"));
273  return;
274  }
275 }
276 
277 std::string PluginName(const std::string& plugin_prefix,
278  const std::string& directive) {
279  // Assuming the directive starts with "--" and ends with "_out" or "_opt",
280  // strip the "--" and "_out/_opt" and add the plugin prefix.
281  return plugin_prefix + "gen-" + directive.substr(2, directive.size() - 6);
282 }
283 
284 } // namespace
285 
286 // A MultiFileErrorCollector that prints errors to stderr.
287 class CommandLineInterface::ErrorPrinter
288  : public MultiFileErrorCollector,
289  public io::ErrorCollector,
290  public DescriptorPool::ErrorCollector {
291  public:
293  : format_(format),
294  tree_(tree),
298 
299  // implements MultiFileErrorCollector ------------------------------
300  void AddError(const std::string& filename, int line, int column,
301  const std::string& message) override {
302  found_errors_ = true;
303  AddErrorOrWarning(filename, line, column, message, "error", std::cerr);
304  }
305 
306  void AddWarning(const std::string& filename, int line, int column,
307  const std::string& message) override {
308  found_warnings_ = true;
309  AddErrorOrWarning(filename, line, column, message, "warning", std::clog);
310  }
311 
312  // implements io::ErrorCollector -----------------------------------
313  void AddError(int line, int column, const std::string& message) override {
314  AddError("input", line, column, message);
315  }
316 
317  void AddWarning(int line, int column, const std::string& message) override {
318  AddErrorOrWarning("input", line, column, message, "warning", std::clog);
319  }
320 
321  // implements DescriptorPool::ErrorCollector-------------------------
323  const Message* descriptor, ErrorLocation location,
324  const std::string& message) override {
325  AddErrorOrWarning(filename, -1, -1, message, "error", std::cerr);
326  }
327 
329  const Message* descriptor, ErrorLocation location,
330  const std::string& message) override {
331  AddErrorOrWarning(filename, -1, -1, message, "warning", std::clog);
332  }
333 
334  bool FoundErrors() const { return found_errors_; }
335 
336  bool FoundWarnings() const { return found_warnings_; }
337 
338  private:
339  void AddErrorOrWarning(const std::string& filename, int line, int column,
340  const std::string& message, const std::string& type,
341  std::ostream& out) {
342  // Print full path when running under MSVS
343  std::string dfile;
346  out << dfile;
347  } else {
348  out << filename;
349  }
350 
351  // Users typically expect 1-based line/column numbers, so we add 1
352  // to each here.
353  if (line != -1) {
354  // Allow for both GCC- and Visual-Studio-compatible output.
355  switch (format_) {
357  out << ":" << (line + 1) << ":" << (column + 1);
358  break;
360  out << "(" << (line + 1) << ") : " << type
361  << " in column=" << (column + 1);
362  break;
363  }
364  }
365 
366  if (type == "warning") {
367  out << ": warning: " << message << std::endl;
368  } else {
369  out << ": " << message << std::endl;
370  }
371  }
372 
373  const ErrorFormat format_;
375  bool found_errors_;
377 };
378 
379 // -------------------------------------------------------------------
380 
381 // A GeneratorContext implementation that buffers files in memory, then dumps
382 // them all to disk on demand.
384  public:
385  GeneratorContextImpl(const std::vector<const FileDescriptor*>& parsed_files);
386 
387  // Write all files in the directory to disk at the given output location,
388  // which must end in a '/'.
389  bool WriteAllToDisk(const std::string& prefix);
390 
391  // Write the contents of this directory to a ZIP-format archive with the
392  // given name.
393  bool WriteAllToZip(const std::string& filename);
394 
395  // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR
396  // format, unless one has already been written.
397  void AddJarManifest();
398 
399  // Get name of all output files.
400  void GetOutputFilenames(std::vector<std::string>* output_filenames);
401 
402  // implements GeneratorContext --------------------------------------
406  const std::string& filename, const std::string& insertion_point) override;
408  const std::string& filename, const std::string& insertion_point,
409  const google::protobuf::GeneratedCodeInfo& info) override;
410  void ListParsedFiles(std::vector<const FileDescriptor*>* output) override {
412  }
413 
414  private:
415  friend class MemoryOutputStream;
416 
417  // The files_ field maps from path keys to file content values. It's a map
418  // instead of an unordered_map so that files are written in order (good when
419  // writing zips).
420  std::map<std::string, std::string> files_;
421  const std::vector<const FileDescriptor*>& parsed_files_;
422  bool had_error_;
423 };
424 
426  : public io::ZeroCopyOutputStream {
427  public:
428  MemoryOutputStream(GeneratorContextImpl* directory,
429  const std::string& filename, bool append_mode);
430  MemoryOutputStream(GeneratorContextImpl* directory,
431  const std::string& filename,
432  const std::string& insertion_point);
433  MemoryOutputStream(GeneratorContextImpl* directory,
434  const std::string& filename,
435  const std::string& insertion_point,
436  const google::protobuf::GeneratedCodeInfo& info);
437  virtual ~MemoryOutputStream();
438 
439  // implements ZeroCopyOutputStream ---------------------------------
440  bool Next(void** data, int* size) override {
441  return inner_->Next(data, size);
442  }
443  void BackUp(int count) override { inner_->BackUp(count); }
444  int64_t ByteCount() const override { return inner_->ByteCount(); }
445 
446  private:
447  // Checks to see if "filename_.pb.meta" exists in directory_; if so, fixes the
448  // offsets in that GeneratedCodeInfo record to reflect bytes inserted in
449  // filename_ at original offset insertion_offset with length insertion_length.
450  // Also adds in the data from info_to_insert_ with updated offsets governed by
451  // insertion_offset and indent_length. We assume that insertions will not
452  // occur within any given annotated span of text. insertion_content must end
453  // with an endline.
454  void UpdateMetadata(const std::string& insertion_content,
455  size_t insertion_offset, size_t insertion_length,
456  size_t indent_length);
457 
458  // Inserts info_to_insert_ into target_info, assuming that the relevant
459  // insertion was made at insertion_offset in file_content with the given
460  // indent_length. insertion_content must end with an endline.
461  void InsertShiftedInfo(const std::string& insertion_content,
462  size_t insertion_offset, size_t indent_length,
463  google::protobuf::GeneratedCodeInfo& target_info);
464 
465  // Where to insert the string when it's done.
469 
470  // The string we're building.
472 
473  // Whether we should append the output stream to the existing file.
474  bool append_mode_;
475 
476  // StringOutputStream writing to data_.
477  std::unique_ptr<io::StringOutputStream> inner_;
478 
479  // The GeneratedCodeInfo to insert at the insertion point.
480  google::protobuf::GeneratedCodeInfo info_to_insert_;
481 };
482 
483 // -------------------------------------------------------------------
484 
486  const std::vector<const FileDescriptor*>& parsed_files)
487  : parsed_files_(parsed_files), had_error_(false) {}
488 
490  const std::string& prefix) {
491  if (had_error_) {
492  return false;
493  }
494 
495  if (!VerifyDirectoryExists(prefix)) {
496  return false;
497  }
498 
499  for (const auto& pair : files_) {
500  const std::string& relative_filename = pair.first;
501  const char* data = pair.second.data();
502  int size = pair.second.size();
503 
504  if (!TryCreateParentDirectory(prefix, relative_filename)) {
505  return false;
506  }
508 
509  // Create the output file.
510  int file_descriptor;
511  do {
512  file_descriptor =
513  open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
514  } while (file_descriptor < 0 && errno == EINTR);
515 
516  if (file_descriptor < 0) {
517  int error = errno;
518  std::cerr << filename << ": " << strerror(error);
519  return false;
520  }
521 
522  // Write the file.
523  while (size > 0) {
524  int write_result;
525  do {
526  write_result = write(file_descriptor, data, size);
527  } while (write_result < 0 && errno == EINTR);
528 
529  if (write_result <= 0) {
530  // Write error.
531 
532  // FIXME(kenton): According to the man page, if write() returns zero,
533  // there was no error; write() simply did not write anything. It's
534  // unclear under what circumstances this might happen, but presumably
535  // errno won't be set in this case. I am confused as to how such an
536  // event should be handled. For now I'm treating it as an error,
537  // since retrying seems like it could lead to an infinite loop. I
538  // suspect this never actually happens anyway.
539 
540  if (write_result < 0) {
541  int error = errno;
542  std::cerr << filename << ": write: " << strerror(error);
543  } else {
544  std::cerr << filename << ": write() returned zero?" << std::endl;
545  }
546  return false;
547  }
548 
549  data += write_result;
550  size -= write_result;
551  }
552 
553  if (close(file_descriptor) != 0) {
554  int error = errno;
555  std::cerr << filename << ": close: " << strerror(error);
556  return false;
557  }
558  }
559 
560  return true;
561 }
562 
564  const std::string& filename) {
565  if (had_error_) {
566  return false;
567  }
568 
569  // Create the output file.
570  int file_descriptor;
571  do {
572  file_descriptor =
573  open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
574  } while (file_descriptor < 0 && errno == EINTR);
575 
576  if (file_descriptor < 0) {
577  int error = errno;
578  std::cerr << filename << ": " << strerror(error);
579  return false;
580  }
581 
582  // Create the ZipWriter
583  io::FileOutputStream stream(file_descriptor);
584  ZipWriter zip_writer(&stream);
585 
586  for (const auto& pair : files_) {
587  zip_writer.Write(pair.first, pair.second);
588  }
589 
590  zip_writer.WriteDirectory();
591 
592  if (stream.GetErrno() != 0) {
593  std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
594  return false;
595  }
596 
597  if (!stream.Close()) {
598  std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
599  return false;
600  }
601 
602  return true;
603 }
604 
606  auto pair = files_.insert({"META-INF/MANIFEST.MF", ""});
607  if (pair.second) {
608  pair.first->second =
609  "Manifest-Version: 1.0\n"
610  "Created-By: 1.6.0 (protoc)\n"
611  "\n";
612  }
613 }
614 
616  std::vector<std::string>* output_filenames) {
617  for (const auto& pair : files_) {
618  output_filenames->push_back(pair.first);
619  }
620 }
621 
623  const std::string& filename) {
624  return new MemoryOutputStream(this, filename, false);
625 }
626 
629  const std::string& filename) {
630  return new MemoryOutputStream(this, filename, true);
631 }
632 
635  const std::string& filename, const std::string& insertion_point) {
636  return new MemoryOutputStream(this, filename, insertion_point);
637 }
638 
641  const std::string& filename, const std::string& insertion_point,
642  const google::protobuf::GeneratedCodeInfo& info) {
643  return new MemoryOutputStream(this, filename, insertion_point, info);
644 }
645 
646 // -------------------------------------------------------------------
647 
650  bool append_mode)
651  : directory_(directory),
652  filename_(filename),
653  append_mode_(append_mode),
654  inner_(new io::StringOutputStream(&data_)) {}
655 
657  GeneratorContextImpl* directory, const std::string& filename,
658  const std::string& insertion_point)
659  : directory_(directory),
660  filename_(filename),
661  insertion_point_(insertion_point),
662  inner_(new io::StringOutputStream(&data_)) {}
663 
666  const std::string& insertion_point, const google::protobuf::GeneratedCodeInfo& info)
667  : directory_(directory),
668  filename_(filename),
669  insertion_point_(insertion_point),
670  inner_(new io::StringOutputStream(&data_)),
671  info_to_insert_(info) {}
672 
674  const std::string& insertion_content, size_t insertion_offset,
675  size_t indent_length, google::protobuf::GeneratedCodeInfo& target_info) {
676  // Keep track of how much extra data was added for indents before the
677  // current annotation being inserted. `pos` and `source_annotation.begin()`
678  // are offsets in `insertion_content`. `insertion_offset` is updated so that
679  // it can be added to an annotation's `begin` field to reflect that
680  // annotation's updated location after `insertion_content` was inserted into
681  // the target file.
682  size_t pos = 0;
683  insertion_offset += indent_length;
684  for (const auto& source_annotation : info_to_insert_.annotation()) {
685  GeneratedCodeInfo::Annotation* annotation = target_info.add_annotation();
686  int inner_indent = 0;
687  // insertion_content is guaranteed to end in an endline. This last endline
688  // has no effect on indentation.
689  for (; pos < source_annotation.end() && pos < insertion_content.size() - 1;
690  ++pos) {
691  if (insertion_content[pos] == '\n') {
692  if (pos >= source_annotation.begin()) {
693  // The beginning of the annotation is at insertion_offset, but the end
694  // can still move further in the target file.
695  inner_indent += indent_length;
696  } else {
697  insertion_offset += indent_length;
698  }
699  }
700  }
701  *annotation = source_annotation;
702  annotation->set_begin(annotation->begin() + insertion_offset);
703  insertion_offset += inner_indent;
704  annotation->set_end(annotation->end() + insertion_offset);
705  }
706 }
707 
709  const std::string& insertion_content, size_t insertion_offset,
710  size_t insertion_length, size_t indent_length) {
711  auto it = directory_->files_.find(filename_ + ".pb.meta");
712  if (it == directory_->files_.end() && info_to_insert_.annotation().empty()) {
713  // No metadata was recorded for this file.
714  return;
715  }
717  bool is_text_format = false;
718  std::string* encoded_data = nullptr;
719  if (it != directory_->files_.end()) {
720  encoded_data = &it->second;
721  // Try to decode a GeneratedCodeInfo proto from the .pb.meta file. It may be
722  // in wire or text format. Keep the same format when the data is written out
723  // later.
724  if (!metadata.ParseFromString(*encoded_data)) {
725  if (!TextFormat::ParseFromString(*encoded_data, &metadata)) {
726  // The metadata is invalid.
727  std::cerr
728  << filename_
729  << ".pb.meta: Could not parse metadata as wire or text format."
730  << std::endl;
731  return;
732  }
733  // Generators that use the public plugin interface emit text-format
734  // metadata (because in the public plugin protocol, file content must be
735  // UTF8-encoded strings).
736  is_text_format = true;
737  }
738  } else {
739  // Create a new file to store the new metadata in info_to_insert_.
740  encoded_data =
741  &directory_->files_.insert({filename_ + ".pb.meta", ""}).first->second;
742  }
743  GeneratedCodeInfo new_metadata;
744  bool crossed_offset = false;
745  size_t to_add = 0;
746  for (const auto& source_annotation : metadata.annotation()) {
747  // The first time an annotation at or after the insertion point is found,
748  // insert the new metadata from info_to_insert_. Shift all annotations
749  // after the new metadata by the length of the text that was inserted
750  // (including any additional indent length).
751  if (source_annotation.begin() >= insertion_offset && !crossed_offset) {
752  crossed_offset = true;
753  InsertShiftedInfo(insertion_content, insertion_offset, indent_length,
754  new_metadata);
755  to_add += insertion_length;
756  }
757  GeneratedCodeInfo::Annotation* annotation = new_metadata.add_annotation();
758  *annotation = source_annotation;
759  annotation->set_begin(annotation->begin() + to_add);
760  annotation->set_end(annotation->end() + to_add);
761  }
762  // If there were never any annotations at or after the insertion point,
763  // make sure to still insert the new metadata from info_to_insert_.
764  if (!crossed_offset) {
765  InsertShiftedInfo(insertion_content, insertion_offset, indent_length,
766  new_metadata);
767  }
768  if (is_text_format) {
769  TextFormat::PrintToString(new_metadata, encoded_data);
770  } else {
771  new_metadata.SerializeToString(encoded_data);
772  }
773 }
774 
776  // Make sure all data has been written.
777  inner_.reset();
778 
779  // Insert into the directory.
780  auto pair = directory_->files_.insert({filename_, ""});
781  auto it = pair.first;
782  bool already_present = !pair.second;
783 
784  if (insertion_point_.empty()) {
785  // This was just a regular Open().
786  if (already_present) {
787  if (append_mode_) {
788  it->second.append(data_);
789  } else {
790  std::cerr << filename_ << ": Tried to write the same file twice."
791  << std::endl;
792  directory_->had_error_ = true;
793  }
794  return;
795  }
796 
797  it->second.swap(data_);
798  } else {
799  // This was an OpenForInsert().
800 
801  // If the data doesn't end with a clean line break, add one.
802  if (!data_.empty() && data_[data_.size() - 1] != '\n') {
803  data_.push_back('\n');
804  }
805 
806  // Find the file we are going to insert into.
807  if (!already_present) {
808  std::cerr << filename_
809  << ": Tried to insert into file that doesn't exist."
810  << std::endl;
811  directory_->had_error_ = true;
812  return;
813  }
814  std::string* target = &it->second;
815 
816  // Find the insertion point.
817  std::string magic_string =
818  strings::Substitute("@@protoc_insertion_point($0)", insertion_point_);
819  std::string::size_type pos = target->find(magic_string);
820 
821  if (pos == std::string::npos) {
822  std::cerr << filename_ << ": insertion point \"" << insertion_point_
823  << "\" not found." << std::endl;
824  directory_->had_error_ = true;
825  return;
826  }
827 
828  if ((pos > 3) && (target->substr(pos - 3, 2) == "/*")) {
829  // Support for inline "/* @@protoc_insertion_point() */"
830  pos = pos - 3;
831  } else {
832  // Seek backwards to the beginning of the line, which is where we will
833  // insert the data. Note that this has the effect of pushing the
834  // insertion point down, so the data is inserted before it. This is
835  // intentional because it means that multiple insertions at the same point
836  // will end up in the expected order in the final output.
837  pos = target->find_last_of('\n', pos);
838  if (pos == std::string::npos) {
839  // Insertion point is on the first line.
840  pos = 0;
841  } else {
842  // Advance to character after '\n'.
843  ++pos;
844  }
845  }
846 
847  // Extract indent.
849  target->find_first_not_of(" \t", pos) - pos);
850 
851  if (indent_.empty()) {
852  // No indent. This makes things easier.
853  target->insert(pos, data_);
854  UpdateMetadata(data_, pos, data_.size(), 0);
855  } else {
856  // Calculate how much space we need.
857  int indent_size = 0;
858  for (int i = 0; i < data_.size(); i++) {
859  if (data_[i] == '\n') indent_size += indent_.size();
860  }
861 
862  // Make a hole for it.
863  target->insert(pos, data_.size() + indent_size, '\0');
864 
865  // Now copy in the data.
866  std::string::size_type data_pos = 0;
867  char* target_ptr = ::google::protobuf::string_as_array(target) + pos;
868  while (data_pos < data_.size()) {
869  // Copy indent.
870  memcpy(target_ptr, indent_.data(), indent_.size());
871  target_ptr += indent_.size();
872 
873  // Copy line from data_.
874  // We already guaranteed that data_ ends with a newline (above), so this
875  // search can't fail.
876  std::string::size_type line_length =
877  data_.find_first_of('\n', data_pos) + 1 - data_pos;
878  memcpy(target_ptr, data_.data() + data_pos, line_length);
879  target_ptr += line_length;
880  data_pos += line_length;
881  }
882  UpdateMetadata(data_, pos, data_.size() + indent_size, indent_.size());
883 
884  GOOGLE_CHECK_EQ(target_ptr,
885  ::google::protobuf::string_as_array(target) + pos + data_.size() + indent_size);
886  }
887  }
888 }
889 
890 // ===================================================================
891 
892 #if defined(_WIN32) && !defined(__CYGWIN__)
893 const char* const CommandLineInterface::kPathSeparator = ";";
894 #else
895 const char* const CommandLineInterface::kPathSeparator = ":";
896 #endif
897 
900  kDefaultDirectDependenciesViolationMsg) {}
901 
903 
905  CodeGenerator* generator,
906  const std::string& help_text) {
907  GeneratorInfo info;
908  info.flag_name = flag_name;
909  info.generator = generator;
910  info.help_text = help_text;
911  generators_by_flag_name_[flag_name] = info;
912 }
913 
915  const std::string& flag_name, const std::string& option_flag_name,
916  CodeGenerator* generator, const std::string& help_text) {
917  GeneratorInfo info;
918  info.flag_name = flag_name;
919  info.option_flag_name = option_flag_name;
920  info.generator = generator;
921  info.help_text = help_text;
922  generators_by_flag_name_[flag_name] = info;
923  generators_by_option_name_[option_flag_name] = info;
924 }
925 
926 void CommandLineInterface::AllowPlugins(const std::string& exe_name_prefix) {
927  plugin_prefix_ = exe_name_prefix;
928 }
929 
930 namespace {
931 
932 bool ContainsProto3Optional(const Descriptor* desc) {
933  for (int i = 0; i < desc->field_count(); i++) {
934  if (desc->field(i)->has_optional_keyword()) {
935  return true;
936  }
937  }
938  for (int i = 0; i < desc->nested_type_count(); i++) {
939  if (ContainsProto3Optional(desc->nested_type(i))) {
940  return true;
941  }
942  }
943  return false;
944 }
945 
946 bool ContainsProto3Optional(const FileDescriptor* file) {
947  if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) {
948  for (int i = 0; i < file->message_type_count(); i++) {
949  if (ContainsProto3Optional(file->message_type(i))) {
950  return true;
951  }
952  }
953  }
954  return false;
955 }
956 
957 } // namespace
958 
959 namespace {
960 std::unique_ptr<SimpleDescriptorDatabase>
961 PopulateSingleSimpleDescriptorDatabase(const std::string& descriptor_set_name);
962 }
963 
964 int CommandLineInterface::Run(int argc, const char* const argv[]) {
965  Clear();
966  switch (ParseArguments(argc, argv)) {
968  return 0;
969  case PARSE_ARGUMENT_FAIL:
970  return 1;
972  break;
973  }
974 
975  std::vector<const FileDescriptor*> parsed_files;
976  std::unique_ptr<DiskSourceTree> disk_source_tree;
977  std::unique_ptr<ErrorPrinter> error_collector;
978  std::unique_ptr<DescriptorPool> descriptor_pool;
979 
980  // The SimpleDescriptorDatabases here are the constituents of the
981  // MergedDescriptorDatabase descriptor_set_in_database, so this vector is for
982  // managing their lifetimes. Its scope should match descriptor_set_in_database
983  std::vector<std::unique_ptr<SimpleDescriptorDatabase>>
984  databases_per_descriptor_set;
985  std::unique_ptr<MergedDescriptorDatabase> descriptor_set_in_database;
986 
987  std::unique_ptr<SourceTreeDescriptorDatabase> source_tree_database;
988 
989  // Any --descriptor_set_in FileDescriptorSet objects will be used as a
990  // fallback to input_files on command line, so create that db first.
991  if (!descriptor_set_in_names_.empty()) {
992  for (const std::string& name : descriptor_set_in_names_) {
993  std::unique_ptr<SimpleDescriptorDatabase> database_for_descriptor_set =
994  PopulateSingleSimpleDescriptorDatabase(name);
995  if (!database_for_descriptor_set) {
996  return EXIT_FAILURE;
997  }
998  databases_per_descriptor_set.push_back(
999  std::move(database_for_descriptor_set));
1000  }
1001 
1002  std::vector<DescriptorDatabase*> raw_databases_per_descriptor_set;
1003  raw_databases_per_descriptor_set.reserve(
1004  databases_per_descriptor_set.size());
1005  for (const std::unique_ptr<SimpleDescriptorDatabase>& db :
1006  databases_per_descriptor_set) {
1007  raw_databases_per_descriptor_set.push_back(db.get());
1008  }
1009  descriptor_set_in_database.reset(
1010  new MergedDescriptorDatabase(raw_databases_per_descriptor_set));
1011  }
1012 
1013  if (proto_path_.empty()) {
1014  // If there are no --proto_path flags, then just look in the specified
1015  // --descriptor_set_in files. But first, verify that the input files are
1016  // there.
1017  if (!VerifyInputFilesInDescriptors(descriptor_set_in_database.get())) {
1018  return 1;
1019  }
1020 
1021  error_collector.reset(new ErrorPrinter(error_format_));
1022  descriptor_pool.reset(new DescriptorPool(descriptor_set_in_database.get(),
1023  error_collector.get()));
1024  } else {
1025  disk_source_tree.reset(new DiskSourceTree());
1026  if (!InitializeDiskSourceTree(disk_source_tree.get(),
1027  descriptor_set_in_database.get())) {
1028  return 1;
1029  }
1030 
1031  error_collector.reset(
1032  new ErrorPrinter(error_format_, disk_source_tree.get()));
1033 
1034  source_tree_database.reset(new SourceTreeDescriptorDatabase(
1035  disk_source_tree.get(), descriptor_set_in_database.get()));
1036  source_tree_database->RecordErrorsTo(error_collector.get());
1037 
1038  descriptor_pool.reset(new DescriptorPool(
1039  source_tree_database.get(),
1040  source_tree_database->GetValidationErrorCollector()));
1041  }
1042 
1043  descriptor_pool->EnforceWeakDependencies(true);
1044  if (!ParseInputFiles(descriptor_pool.get(), disk_source_tree.get(),
1045  &parsed_files)) {
1046  return 1;
1047  }
1048 
1049 
1050  // We construct a separate GeneratorContext for each output location. Note
1051  // that two code generators may output to the same location, in which case
1052  // they should share a single GeneratorContext so that OpenForInsert() works.
1053  GeneratorContextMap output_directories;
1054 
1055  // Generate output.
1056  if (mode_ == MODE_COMPILE) {
1057  for (int i = 0; i < output_directives_.size(); i++) {
1058  std::string output_location = output_directives_[i].output_location;
1059  if (!HasSuffixString(output_location, ".zip") &&
1060  !HasSuffixString(output_location, ".jar") &&
1061  !HasSuffixString(output_location, ".srcjar")) {
1062  AddTrailingSlash(&output_location);
1063  }
1064 
1065  auto& generator = output_directories[output_location];
1066 
1067  if (!generator) {
1068  // First time we've seen this output location.
1069  generator.reset(new GeneratorContextImpl(parsed_files));
1070  }
1071 
1072  if (!GenerateOutput(parsed_files, output_directives_[i],
1073  generator.get())) {
1074  return 1;
1075  }
1076  }
1077  }
1078 
1079  // Write all output to disk.
1080  for (const auto& pair : output_directories) {
1081  const std::string& location = pair.first;
1082  GeneratorContextImpl* directory = pair.second.get();
1083  if (HasSuffixString(location, "/")) {
1084  if (!directory->WriteAllToDisk(location)) {
1085  return 1;
1086  }
1087  } else {
1088  if (HasSuffixString(location, ".jar")) {
1089  directory->AddJarManifest();
1090  }
1091 
1092  if (!directory->WriteAllToZip(location)) {
1093  return 1;
1094  }
1095  }
1096  }
1097 
1098  if (!dependency_out_name_.empty()) {
1099  GOOGLE_DCHECK(disk_source_tree.get());
1100  if (!GenerateDependencyManifestFile(parsed_files, output_directories,
1101  disk_source_tree.get())) {
1102  return 1;
1103  }
1104  }
1105 
1106  if (!descriptor_set_out_name_.empty()) {
1107  if (!WriteDescriptorSet(parsed_files)) {
1108  return 1;
1109  }
1110  }
1111 
1112  if (mode_ == MODE_ENCODE || mode_ == MODE_DECODE) {
1113  if (codec_type_.empty()) {
1114  // HACK: Define an EmptyMessage type to use for decoding.
1117  file.set_name("empty_message.proto");
1118  file.add_message_type()->set_name("EmptyMessage");
1119  GOOGLE_CHECK(pool.BuildFile(file) != NULL);
1120  codec_type_ = "EmptyMessage";
1121  if (!EncodeOrDecode(&pool)) {
1122  return 1;
1123  }
1124  } else {
1125  if (!EncodeOrDecode(descriptor_pool.get())) {
1126  return 1;
1127  }
1128  }
1129  }
1130 
1131  if (error_collector->FoundErrors() ||
1132  (fatal_warnings_ && error_collector->FoundWarnings())) {
1133  return 1;
1134  }
1135 
1136  if (mode_ == MODE_PRINT) {
1137  switch (print_mode_) {
1138  case PRINT_FREE_FIELDS:
1139  for (int i = 0; i < parsed_files.size(); ++i) {
1140  const FileDescriptor* fd = parsed_files[i];
1141  for (int j = 0; j < fd->message_type_count(); ++j) {
1142  PrintFreeFieldNumbers(fd->message_type(j));
1143  }
1144  }
1145  break;
1146  case PRINT_NONE:
1147  GOOGLE_LOG(ERROR) << "If the code reaches here, it usually means a bug of "
1148  "flag parsing in the CommandLineInterface.";
1149  return 1;
1150 
1151  // Do not add a default case.
1152  }
1153  }
1154 
1155  return 0;
1156 }
1157 
1159  DiskSourceTree* source_tree, DescriptorDatabase* fallback_database) {
1160  AddDefaultProtoPaths(&proto_path_);
1161 
1162  // Set up the source tree.
1163  for (int i = 0; i < proto_path_.size(); i++) {
1164  source_tree->MapPath(proto_path_[i].first, proto_path_[i].second);
1165  }
1166 
1167  // Map input files to virtual paths if possible.
1168  if (!MakeInputsBeProtoPathRelative(source_tree, fallback_database)) {
1169  return false;
1170  }
1171 
1172  return true;
1173 }
1174 
1175 namespace {
1176 std::unique_ptr<SimpleDescriptorDatabase>
1177 PopulateSingleSimpleDescriptorDatabase(const std::string& descriptor_set_name) {
1178  int fd;
1179  do {
1180  fd = open(descriptor_set_name.c_str(), O_RDONLY | O_BINARY);
1181  } while (fd < 0 && errno == EINTR);
1182  if (fd < 0) {
1183  std::cerr << descriptor_set_name << ": " << strerror(ENOENT) << std::endl;
1184  return nullptr;
1185  }
1186 
1187  FileDescriptorSet file_descriptor_set;
1188  bool parsed = file_descriptor_set.ParseFromFileDescriptor(fd);
1189  if (close(fd) != 0) {
1190  std::cerr << descriptor_set_name << ": close: " << strerror(errno)
1191  << std::endl;
1192  return nullptr;
1193  }
1194 
1195  if (!parsed) {
1196  std::cerr << descriptor_set_name << ": Unable to parse." << std::endl;
1197  return nullptr;
1198  }
1199 
1200  std::unique_ptr<SimpleDescriptorDatabase> database{
1201  new SimpleDescriptorDatabase()};
1202 
1203  for (int j = 0; j < file_descriptor_set.file_size(); j++) {
1204  FileDescriptorProto previously_added_file_descriptor_proto;
1205  if (database->FindFileByName(file_descriptor_set.file(j).name(),
1206  &previously_added_file_descriptor_proto)) {
1207  // already present - skip
1208  continue;
1209  }
1210  if (!database->Add(file_descriptor_set.file(j))) {
1211  return nullptr;
1212  }
1213  }
1214  return database;
1215 }
1216 
1217 } // namespace
1218 
1219 
1222  for (const auto& input_file : input_files_) {
1223  FileDescriptorProto file_descriptor;
1224  if (!database->FindFileByName(input_file, &file_descriptor)) {
1225  std::cerr << "Could not find file in descriptor database: " << input_file
1226  << ": " << strerror(ENOENT) << std::endl;
1227  return false;
1228  }
1229 
1230  // Enforce --disallow_services.
1231  if (disallow_services_ && file_descriptor.service_size() > 0) {
1232  std::cerr << file_descriptor.name()
1233  << ": This file contains services, but "
1234  "--disallow_services was used."
1235  << std::endl;
1236  return false;
1237  }
1238 
1239  }
1240  return true;
1241 }
1242 
1244  DescriptorPool* descriptor_pool, DiskSourceTree* source_tree,
1245  std::vector<const FileDescriptor*>* parsed_files) {
1246 
1247  if (!proto_path_.empty()) {
1248  // Track unused imports in all source files that were loaded from the
1249  // filesystem. We do not track unused imports for files loaded from
1250  // descriptor sets as they may be programmatically generated in which case
1251  // exerting this level of rigor is less desirable. We're also making the
1252  // assumption that the initial parse of the proto from the filesystem
1253  // was rigorous in checking unused imports and that the descriptor set
1254  // being parsed was produced then and that it was subsequent mutations
1255  // of that descriptor set that left unused imports.
1256  //
1257  // Note that relying on proto_path exclusively is limited in that we may
1258  // be loading descriptors from both the filesystem and descriptor sets
1259  // depending on the invocation. At least for invocations that are
1260  // exclusively reading from descriptor sets, we can eliminate this failure
1261  // condition.
1262  for (const auto& input_file : input_files_) {
1263  descriptor_pool->AddUnusedImportTrackFile(input_file);
1264  }
1265  }
1266 
1267  bool result = true;
1268  // Parse each file.
1269  for (const auto& input_file : input_files_) {
1270  // Import the file.
1271  const FileDescriptor* parsed_file =
1272  descriptor_pool->FindFileByName(input_file);
1273  if (parsed_file == NULL) {
1274  result = false;
1275  break;
1276  }
1277  parsed_files->push_back(parsed_file);
1278 
1279  // Enforce --disallow_services.
1280  if (disallow_services_ && parsed_file->service_count() > 0) {
1281  std::cerr << parsed_file->name()
1282  << ": This file contains services, but "
1283  "--disallow_services was used."
1284  << std::endl;
1285  result = false;
1286  break;
1287  }
1288 
1289 
1290  // Enforce --direct_dependencies
1292  bool indirect_imports = false;
1293  for (int i = 0; i < parsed_file->dependency_count(); i++) {
1294  if (direct_dependencies_.find(parsed_file->dependency(i)->name()) ==
1295  direct_dependencies_.end()) {
1296  indirect_imports = true;
1297  std::cerr << parsed_file->name() << ": "
1299  parsed_file->dependency(i)->name(),
1300  true /* replace_all */)
1301  << std::endl;
1302  }
1303  }
1304  if (indirect_imports) {
1305  result = false;
1306  break;
1307  }
1308  }
1309  }
1310  descriptor_pool->ClearUnusedImportTrackFiles();
1311  return result;
1312 }
1313 
1315  // Clear all members that are set by Run(). Note that we must not clear
1316  // members which are set by other methods before Run() is called.
1317  executable_name_.clear();
1318  proto_path_.clear();
1319  input_files_.clear();
1320  direct_dependencies_.clear();
1321  direct_dependencies_violation_msg_ = kDefaultDirectDependenciesViolationMsg;
1322  output_directives_.clear();
1323  codec_type_.clear();
1324  descriptor_set_in_names_.clear();
1325  descriptor_set_out_name_.clear();
1326  dependency_out_name_.clear();
1327 
1328 
1329  mode_ = MODE_COMPILE;
1333  disallow_services_ = false;
1335  deterministic_output_ = false;
1336 }
1337 
1339  DiskSourceTree* source_tree, std::string* proto,
1340  DescriptorDatabase* fallback_database) {
1341  // If it's in the fallback db, don't report non-existent file errors.
1342  FileDescriptorProto fallback_file;
1343  bool in_fallback_database =
1344  fallback_database != nullptr &&
1345  fallback_database->FindFileByName(*proto, &fallback_file);
1346 
1347  // If the input file path is not a physical file path, it must be a virtual
1348  // path.
1349  if (access(proto->c_str(), F_OK) < 0) {
1350  std::string disk_file;
1351  if (source_tree->VirtualFileToDiskFile(*proto, &disk_file) ||
1352  in_fallback_database) {
1353  return true;
1354  } else {
1355  std::cerr << "Could not make proto path relative: " << *proto << ": "
1356  << strerror(ENOENT) << std::endl;
1357  return false;
1358  }
1359  }
1360 
1361  std::string virtual_file, shadowing_disk_file;
1362  switch (source_tree->DiskFileToVirtualFile(*proto, &virtual_file,
1363  &shadowing_disk_file)) {
1365  *proto = virtual_file;
1366  break;
1368  std::cerr << *proto << ": Input is shadowed in the --proto_path by \""
1369  << shadowing_disk_file
1370  << "\". Either use the latter file as your input or reorder "
1371  "the --proto_path so that the former file's location "
1372  "comes first."
1373  << std::endl;
1374  return false;
1376  if (in_fallback_database) {
1377  return true;
1378  }
1379  std::string error_str = source_tree->GetLastErrorMessage().empty()
1380  ? strerror(errno)
1381  : source_tree->GetLastErrorMessage();
1382  std::cerr << "Could not map to virtual file: " << *proto << ": "
1383  << error_str << std::endl;
1384  return false;
1385  }
1387  // Try to interpret the path as a virtual path.
1388  std::string disk_file;
1389  if (source_tree->VirtualFileToDiskFile(*proto, &disk_file) ||
1390  in_fallback_database) {
1391  return true;
1392  } else {
1393  // The input file path can't be mapped to any --proto_path and it also
1394  // can't be interpreted as a virtual path.
1395  std::cerr
1396  << *proto
1397  << ": File does not reside within any path "
1398  "specified using --proto_path (or -I). You must specify a "
1399  "--proto_path which encompasses this file. Note that the "
1400  "proto_path must be an exact prefix of the .proto file "
1401  "names -- protoc is too dumb to figure out when two paths "
1402  "(e.g. absolute and relative) are equivalent (it's harder "
1403  "than you think)."
1404  << std::endl;
1405  return false;
1406  }
1407  }
1408  }
1409  return true;
1410 }
1411 
1413  DiskSourceTree* source_tree, DescriptorDatabase* fallback_database) {
1414  for (auto& input_file : input_files_) {
1415  if (!MakeProtoProtoPathRelative(source_tree, &input_file,
1416  fallback_database)) {
1417  return false;
1418  }
1419  }
1420 
1421  return true;
1422 }
1423 
1424 
1426  const std::string& file, std::vector<std::string>* arguments) {
1427  // The argument file is searched in the working directory only. We don't
1428  // use the proto import path here.
1429  std::ifstream file_stream(file.c_str());
1430  if (!file_stream.is_open()) {
1431  return false;
1432  }
1434  // We don't support any kind of shell expansion right now.
1435  while (std::getline(file_stream, argument)) {
1436  arguments->push_back(argument);
1437  }
1438  return true;
1439 }
1440 
1442  int argc, const char* const argv[]) {
1443  executable_name_ = argv[0];
1444 
1445  std::vector<std::string> arguments;
1446  for (int i = 1; i < argc; ++i) {
1447  if (argv[i][0] == '@') {
1448  if (!ExpandArgumentFile(argv[i] + 1, &arguments)) {
1449  std::cerr << "Failed to open argument file: " << (argv[i] + 1)
1450  << std::endl;
1451  return PARSE_ARGUMENT_FAIL;
1452  }
1453  continue;
1454  }
1455  arguments.push_back(argv[i]);
1456  }
1457 
1458  // if no arguments are given, show help
1459  if (arguments.empty()) {
1460  PrintHelpText();
1461  return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
1462  }
1463 
1464  // Iterate through all arguments and parse them.
1465  for (int i = 0; i < arguments.size(); ++i) {
1467 
1468  if (ParseArgument(arguments[i].c_str(), &name, &value)) {
1469  // Returned true => Use the next argument as the flag value.
1470  if (i + 1 == arguments.size() || arguments[i + 1][0] == '-') {
1471  std::cerr << "Missing value for flag: " << name << std::endl;
1472  if (name == "--decode") {
1473  std::cerr << "To decode an unknown message, use --decode_raw."
1474  << std::endl;
1475  }
1476  return PARSE_ARGUMENT_FAIL;
1477  } else {
1478  ++i;
1479  value = arguments[i];
1480  }
1481  }
1482 
1485  }
1486 
1487  // Make sure each plugin option has a matching plugin output.
1488  bool foundUnknownPluginOption = false;
1489  for (std::map<std::string, std::string>::const_iterator i =
1490  plugin_parameters_.begin();
1491  i != plugin_parameters_.end(); ++i) {
1492  if (plugins_.find(i->first) != plugins_.end()) {
1493  continue;
1494  }
1495  bool foundImplicitPlugin = false;
1496  for (std::vector<OutputDirective>::const_iterator j =
1497  output_directives_.begin();
1498  j != output_directives_.end(); ++j) {
1499  if (j->generator == NULL) {
1500  std::string plugin_name = PluginName(plugin_prefix_, j->name);
1501  if (plugin_name == i->first) {
1502  foundImplicitPlugin = true;
1503  break;
1504  }
1505  }
1506  }
1507  if (!foundImplicitPlugin) {
1508  std::cerr << "Unknown flag: "
1509  // strip prefix + "gen-" and add back "_opt"
1510  << "--" + i->first.substr(plugin_prefix_.size() + 4) + "_opt"
1511  << std::endl;
1512  foundUnknownPluginOption = true;
1513  }
1514  }
1515  if (foundUnknownPluginOption) {
1516  return PARSE_ARGUMENT_FAIL;
1517  }
1518 
1519  // The --proto_path & --descriptor_set_in flags both specify places to look
1520  // for proto files. If neither were given, use the current working directory.
1521  if (proto_path_.empty() && descriptor_set_in_names_.empty()) {
1522  // Don't use make_pair as the old/default standard library on Solaris
1523  // doesn't support it without explicit template parameters, which are
1524  // incompatible with C++0x's make_pair.
1525  proto_path_.push_back(std::pair<std::string, std::string>("", "."));
1526  }
1527 
1528  // Check error cases that span multiple flag values.
1529  bool missing_proto_definitions = false;
1530  switch (mode_) {
1531  case MODE_COMPILE:
1532  missing_proto_definitions = input_files_.empty();
1533  break;
1534  case MODE_DECODE:
1535  // Handle --decode_raw separately, since it requires that no proto
1536  // definitions are specified.
1537  if (codec_type_.empty()) {
1538  if (!input_files_.empty() || !descriptor_set_in_names_.empty()) {
1539  std::cerr
1540  << "When using --decode_raw, no input files should be given."
1541  << std::endl;
1542  return PARSE_ARGUMENT_FAIL;
1543  }
1544  missing_proto_definitions = false;
1545  break; // only for --decode_raw
1546  }
1547  // --decode (not raw) is handled the same way as the rest of the modes.
1548  PROTOBUF_FALLTHROUGH_INTENDED;
1549  case MODE_ENCODE:
1550  case MODE_PRINT:
1551  missing_proto_definitions =
1552  input_files_.empty() && descriptor_set_in_names_.empty();
1553  break;
1554  default:
1555  GOOGLE_LOG(FATAL) << "Unexpected mode: " << mode_;
1556  }
1557  if (missing_proto_definitions) {
1558  std::cerr << "Missing input file." << std::endl;
1559  return PARSE_ARGUMENT_FAIL;
1560  }
1561  if (mode_ == MODE_COMPILE && output_directives_.empty() &&
1562  descriptor_set_out_name_.empty()) {
1563  std::cerr << "Missing output directives." << std::endl;
1564  return PARSE_ARGUMENT_FAIL;
1565  }
1566  if (mode_ != MODE_COMPILE && !dependency_out_name_.empty()) {
1567  std::cerr << "Can only use --dependency_out=FILE when generating code."
1568  << std::endl;
1569  return PARSE_ARGUMENT_FAIL;
1570  }
1572  std::cerr << "Can only use --deterministic_output with --encode."
1573  << std::endl;
1574  return PARSE_ARGUMENT_FAIL;
1575  }
1576  if (!dependency_out_name_.empty() && input_files_.size() > 1) {
1577  std::cerr
1578  << "Can only process one input file when using --dependency_out=FILE."
1579  << std::endl;
1580  return PARSE_ARGUMENT_FAIL;
1581  }
1583  std::cerr << "--include_imports only makes sense when combined with "
1584  "--descriptor_set_out."
1585  << std::endl;
1586  }
1588  std::cerr << "--include_source_info only makes sense when combined with "
1589  "--descriptor_set_out."
1590  << std::endl;
1591  }
1592 
1594 }
1595 
1597  std::string* value) {
1598  bool parsed_value = false;
1599 
1600  if (arg[0] != '-') {
1601  // Not a flag.
1602  name->clear();
1603  parsed_value = true;
1604  *value = arg;
1605  } else if (arg[1] == '-') {
1606  // Two dashes: Multi-character name, with '=' separating name and
1607  // value.
1608  const char* equals_pos = strchr(arg, '=');
1609  if (equals_pos != NULL) {
1610  *name = std::string(arg, equals_pos - arg);
1611  *value = equals_pos + 1;
1612  parsed_value = true;
1613  } else {
1614  *name = arg;
1615  }
1616  } else {
1617  // One dash: One-character name, all subsequent characters are the
1618  // value.
1619  if (arg[1] == '\0') {
1620  // arg is just "-". We treat this as an input file, except that at
1621  // present this will just lead to a "file not found" error.
1622  name->clear();
1623  *value = arg;
1624  parsed_value = true;
1625  } else {
1626  *name = std::string(arg, 2);
1627  *value = arg + 2;
1628  parsed_value = !value->empty();
1629  }
1630  }
1631 
1632  // Need to return true iff the next arg should be used as the value for this
1633  // one, false otherwise.
1634 
1635  if (parsed_value) {
1636  // We already parsed a value for this flag.
1637  return false;
1638  }
1639 
1640  if (*name == "-h" || *name == "--help" || *name == "--disallow_services" ||
1641  *name == "--include_imports" || *name == "--include_source_info" ||
1642  *name == "--version" || *name == "--decode_raw" ||
1643  *name == "--print_free_field_numbers" ||
1644  *name == "--experimental_allow_proto3_optional" ||
1645  *name == "--deterministic_output" || *name == "--fatal_warnings") {
1646  // HACK: These are the only flags that don't take a value.
1647  // They probably should not be hard-coded like this but for now it's
1648  // not worth doing better.
1649  return false;
1650  }
1651 
1652  // Next argument is the flag value.
1653  return true;
1654 }
1655 
1658  const std::string& value) {
1659  if (name.empty()) {
1660  // Not a flag. Just a filename.
1661  if (value.empty()) {
1662  std::cerr
1663  << "You seem to have passed an empty string as one of the "
1664  "arguments to "
1665  << executable_name_
1666  << ". This is actually "
1667  "sort of hard to do. Congrats. Unfortunately it is not valid "
1668  "input so the program is going to die now."
1669  << std::endl;
1670  return PARSE_ARGUMENT_FAIL;
1671  }
1672 
1673 #if defined(_WIN32)
1674  // On Windows, the shell (typically cmd.exe) does not expand wildcards in
1675  // file names (e.g. foo\*.proto), so we do it ourselves.
1676  switch (google::protobuf::io::win32::ExpandWildcards(
1677  value,
1678  [this](const string& path) { this->input_files_.push_back(path); })) {
1679  case google::protobuf::io::win32::ExpandWildcardsResult::kSuccess:
1680  break;
1681  case google::protobuf::io::win32::ExpandWildcardsResult::
1682  kErrorNoMatchingFile:
1683  // Path does not exist, is not a file, or it's longer than MAX_PATH and
1684  // long path handling is disabled.
1685  std::cerr << "Invalid file name pattern or missing input file \""
1686  << value << "\"" << std::endl;
1687  return PARSE_ARGUMENT_FAIL;
1688  default:
1689  std::cerr << "Cannot convert path \"" << value
1690  << "\" to or from Windows style" << std::endl;
1691  return PARSE_ARGUMENT_FAIL;
1692  }
1693 #else // not _WIN32
1694  // On other platforms than Windows (e.g. Linux, Mac OS) the shell (typically
1695  // Bash) expands wildcards.
1696  input_files_.push_back(value);
1697 #endif // _WIN32
1698 
1699  } else if (name == "-I" || name == "--proto_path") {
1700  // Java's -classpath (and some other languages) delimits path components
1701  // with colons. Let's accept that syntax too just to make things more
1702  // intuitive.
1703  std::vector<std::string> parts = Split(
1705  true);
1706 
1707  for (int i = 0; i < parts.size(); i++) {
1708  std::string virtual_path;
1709  std::string disk_path;
1710 
1711  std::string::size_type equals_pos = parts[i].find_first_of('=');
1712  if (equals_pos == std::string::npos) {
1713  virtual_path = "";
1714  disk_path = parts[i];
1715  } else {
1716  virtual_path = parts[i].substr(0, equals_pos);
1717  disk_path = parts[i].substr(equals_pos + 1);
1718  }
1719 
1720  if (disk_path.empty()) {
1721  std::cerr
1722  << "--proto_path passed empty directory name. (Use \".\" for "
1723  "current directory.)"
1724  << std::endl;
1725  return PARSE_ARGUMENT_FAIL;
1726  }
1727 
1728  // Make sure disk path exists, warn otherwise.
1729  if (access(disk_path.c_str(), F_OK) < 0) {
1730  // Try the original path; it may have just happened to have a '=' in it.
1731  if (access(parts[i].c_str(), F_OK) < 0) {
1732  std::cerr << disk_path << ": warning: directory does not exist."
1733  << std::endl;
1734  } else {
1735  virtual_path = "";
1736  disk_path = parts[i];
1737  }
1738  }
1739 
1740  // Don't use make_pair as the old/default standard library on Solaris
1741  // doesn't support it without explicit template parameters, which are
1742  // incompatible with C++0x's make_pair.
1743  proto_path_.push_back(
1744  std::pair<std::string, std::string>(virtual_path, disk_path));
1745  }
1746 
1747  } else if (name == "--direct_dependencies") {
1749  std::cerr << name
1750  << " may only be passed once. To specify multiple "
1751  "direct dependencies, pass them all as a single "
1752  "parameter separated by ':'."
1753  << std::endl;
1754  return PARSE_ARGUMENT_FAIL;
1755  }
1756 
1758  std::vector<std::string> direct =
1759  Split(value, ":", true);
1761  direct_dependencies_.insert(direct.begin(), direct.end());
1762 
1763  } else if (name == "--direct_dependencies_violation_msg") {
1765 
1766  } else if (name == "--descriptor_set_in") {
1767  if (!descriptor_set_in_names_.empty()) {
1768  std::cerr << name
1769  << " may only be passed once. To specify multiple "
1770  "descriptor sets, pass them all as a single "
1771  "parameter separated by '"
1772  << CommandLineInterface::kPathSeparator << "'." << std::endl;
1773  return PARSE_ARGUMENT_FAIL;
1774  }
1775  if (value.empty()) {
1776  std::cerr << name << " requires a non-empty value." << std::endl;
1777  return PARSE_ARGUMENT_FAIL;
1778  }
1779  if (!dependency_out_name_.empty()) {
1780  std::cerr << name << " cannot be used with --dependency_out."
1781  << std::endl;
1782  return PARSE_ARGUMENT_FAIL;
1783  }
1784 
1787  true);
1788 
1789  } else if (name == "-o" || name == "--descriptor_set_out") {
1790  if (!descriptor_set_out_name_.empty()) {
1791  std::cerr << name << " may only be passed once." << std::endl;
1792  return PARSE_ARGUMENT_FAIL;
1793  }
1794  if (value.empty()) {
1795  std::cerr << name << " requires a non-empty value." << std::endl;
1796  return PARSE_ARGUMENT_FAIL;
1797  }
1798  if (mode_ != MODE_COMPILE) {
1799  std::cerr
1800  << "Cannot use --encode or --decode and generate descriptors at the "
1801  "same time."
1802  << std::endl;
1803  return PARSE_ARGUMENT_FAIL;
1804  }
1806 
1807  } else if (name == "--dependency_out") {
1808  if (!dependency_out_name_.empty()) {
1809  std::cerr << name << " may only be passed once." << std::endl;
1810  return PARSE_ARGUMENT_FAIL;
1811  }
1812  if (value.empty()) {
1813  std::cerr << name << " requires a non-empty value." << std::endl;
1814  return PARSE_ARGUMENT_FAIL;
1815  }
1816  if (!descriptor_set_in_names_.empty()) {
1817  std::cerr << name << " cannot be used with --descriptor_set_in."
1818  << std::endl;
1819  return PARSE_ARGUMENT_FAIL;
1820  }
1822 
1823  } else if (name == "--include_imports") {
1825  std::cerr << name << " may only be passed once." << std::endl;
1826  return PARSE_ARGUMENT_FAIL;
1827  }
1829 
1830  } else if (name == "--include_source_info") {
1832  std::cerr << name << " may only be passed once." << std::endl;
1833  return PARSE_ARGUMENT_FAIL;
1834  }
1836 
1837  } else if (name == "-h" || name == "--help") {
1838  PrintHelpText();
1839  return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
1840 
1841  } else if (name == "--version") {
1842  if (!version_info_.empty()) {
1843  std::cout << version_info_ << std::endl;
1844  }
1845  std::cout << "libprotoc " << internal::VersionString(PROTOBUF_VERSION)
1846  << PROTOBUF_VERSION_SUFFIX << std::endl;
1847  return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
1848 
1849  } else if (name == "--disallow_services") {
1850  disallow_services_ = true;
1851 
1852 
1853  } else if (name == "--experimental_allow_proto3_optional") {
1854  // Flag is no longer observed, but we allow it for backward compat.
1855  } else if (name == "--encode" || name == "--decode" ||
1856  name == "--decode_raw") {
1857  if (mode_ != MODE_COMPILE) {
1858  std::cerr << "Only one of --encode and --decode can be specified."
1859  << std::endl;
1860  return PARSE_ARGUMENT_FAIL;
1861  }
1862  if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) {
1863  std::cerr << "Cannot use " << name
1864  << " and generate code or descriptors at the same time."
1865  << std::endl;
1866  return PARSE_ARGUMENT_FAIL;
1867  }
1868 
1869  mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
1870 
1871  if (value.empty() && name != "--decode_raw") {
1872  std::cerr << "Type name for " << name << " cannot be blank." << std::endl;
1873  if (name == "--decode") {
1874  std::cerr << "To decode an unknown message, use --decode_raw."
1875  << std::endl;
1876  }
1877  return PARSE_ARGUMENT_FAIL;
1878  } else if (!value.empty() && name == "--decode_raw") {
1879  std::cerr << "--decode_raw does not take a parameter." << std::endl;
1880  return PARSE_ARGUMENT_FAIL;
1881  }
1882 
1883  codec_type_ = value;
1884 
1885  } else if (name == "--deterministic_output") {
1886  deterministic_output_ = true;
1887 
1888  } else if (name == "--error_format") {
1889  if (value == "gcc") {
1891  } else if (value == "msvs") {
1893  } else {
1894  std::cerr << "Unknown error format: " << value << std::endl;
1895  return PARSE_ARGUMENT_FAIL;
1896  }
1897 
1898  } else if (name == "--fatal_warnings") {
1899  if (fatal_warnings_) {
1900  std::cerr << name << " may only be passed once." << std::endl;
1901  return PARSE_ARGUMENT_FAIL;
1902  }
1903  fatal_warnings_ = true;
1904  } else if (name == "--plugin") {
1905  if (plugin_prefix_.empty()) {
1906  std::cerr << "This compiler does not support plugins." << std::endl;
1907  return PARSE_ARGUMENT_FAIL;
1908  }
1909 
1910  std::string plugin_name;
1911  std::string path;
1912 
1913  std::string::size_type equals_pos = value.find_first_of('=');
1914  if (equals_pos == std::string::npos) {
1915  // Use the basename of the file.
1916  std::string::size_type slash_pos = value.find_last_of('/');
1917  if (slash_pos == std::string::npos) {
1918  plugin_name = value;
1919  } else {
1920  plugin_name = value.substr(slash_pos + 1);
1921  }
1922  path = value;
1923  } else {
1924  plugin_name = value.substr(0, equals_pos);
1925  path = value.substr(equals_pos + 1);
1926  }
1927 
1928  plugins_[plugin_name] = path;
1929 
1930  } else if (name == "--print_free_field_numbers") {
1931  if (mode_ != MODE_COMPILE) {
1932  std::cerr << "Cannot use " << name
1933  << " and use --encode, --decode or print "
1934  << "other info at the same time." << std::endl;
1935  return PARSE_ARGUMENT_FAIL;
1936  }
1937  if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) {
1938  std::cerr << "Cannot use " << name
1939  << " and generate code or descriptors at the same time."
1940  << std::endl;
1941  return PARSE_ARGUMENT_FAIL;
1942  }
1943  mode_ = MODE_PRINT;
1945  } else {
1946  // Some other flag. Look it up in the generators list.
1947  const GeneratorInfo* generator_info =
1949  if (generator_info == NULL &&
1950  (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) {
1951  // Check if it's a generator option flag.
1952  generator_info = FindOrNull(generators_by_option_name_, name);
1953  if (generator_info != NULL) {
1955  &generator_parameters_[generator_info->flag_name];
1956  if (!parameters->empty()) {
1957  parameters->append(",");
1958  }
1959  parameters->append(value);
1960  } else if (HasPrefixString(name, "--") && HasSuffixString(name, "_opt")) {
1962  &plugin_parameters_[PluginName(plugin_prefix_, name)];
1963  if (!parameters->empty()) {
1964  parameters->append(",");
1965  }
1966  parameters->append(value);
1967  } else {
1968  std::cerr << "Unknown flag: " << name << std::endl;
1969  return PARSE_ARGUMENT_FAIL;
1970  }
1971  } else {
1972  // It's an output flag. Add it to the output directives.
1973  if (mode_ != MODE_COMPILE) {
1974  std::cerr << "Cannot use --encode, --decode or print .proto info and "
1975  "generate code at the same time."
1976  << std::endl;
1977  return PARSE_ARGUMENT_FAIL;
1978  }
1979 
1980  OutputDirective directive;
1981  directive.name = name;
1982  if (generator_info == NULL) {
1983  directive.generator = NULL;
1984  } else {
1985  directive.generator = generator_info->generator;
1986  }
1987 
1988  // Split value at ':' to separate the generator parameter from the
1989  // filename. However, avoid doing this if the colon is part of a valid
1990  // Windows-style absolute path.
1991  std::string::size_type colon_pos = value.find_first_of(':');
1992  if (colon_pos == std::string::npos || IsWindowsAbsolutePath(value)) {
1993  directive.output_location = value;
1994  } else {
1995  directive.parameter = value.substr(0, colon_pos);
1996  directive.output_location = value.substr(colon_pos + 1);
1997  }
1998 
1999  output_directives_.push_back(directive);
2000  }
2001  }
2002 
2004 }
2005 
2007  // Sorry for indentation here; line wrapping would be uglier.
2008  std::cout << "Usage: " << executable_name_ << " [OPTION] PROTO_FILES";
2009  std::cout << R"(
2010 Parse PROTO_FILES and generate output based on the options given:
2011  -IPATH, --proto_path=PATH Specify the directory in which to search for
2012  imports. May be specified multiple times;
2013  directories will be searched in order. If not
2014  given, the current working directory is used.
2015  If not found in any of the these directories,
2016  the --descriptor_set_in descriptors will be
2017  checked for required proto file.
2018  --version Show version info and exit.
2019  -h, --help Show this text and exit.
2020  --encode=MESSAGE_TYPE Read a text-format message of the given type
2021  from standard input and write it in binary
2022  to standard output. The message type must
2023  be defined in PROTO_FILES or their imports.
2024  --deterministic_output When using --encode, ensure map fields are
2025  deterministically ordered. Note that this order
2026  is not canonical, and changes across builds or
2027  releases of protoc.
2028  --decode=MESSAGE_TYPE Read a binary message of the given type from
2029  standard input and write it in text format
2030  to standard output. The message type must
2031  be defined in PROTO_FILES or their imports.
2032  --decode_raw Read an arbitrary protocol message from
2033  standard input and write the raw tag/value
2034  pairs in text format to standard output. No
2035  PROTO_FILES should be given when using this
2036  flag.
2037  --descriptor_set_in=FILES Specifies a delimited list of FILES
2038  each containing a FileDescriptorSet (a
2039  protocol buffer defined in descriptor.proto).
2040  The FileDescriptor for each of the PROTO_FILES
2041  provided will be loaded from these
2042  FileDescriptorSets. If a FileDescriptor
2043  appears multiple times, the first occurrence
2044  will be used.
2045  -oFILE, Writes a FileDescriptorSet (a protocol buffer,
2046  --descriptor_set_out=FILE defined in descriptor.proto) containing all of
2047  the input files to FILE.
2048  --include_imports When using --descriptor_set_out, also include
2049  all dependencies of the input files in the
2050  set, so that the set is self-contained.
2051  --include_source_info When using --descriptor_set_out, do not strip
2052  SourceCodeInfo from the FileDescriptorProto.
2053  This results in vastly larger descriptors that
2054  include information about the original
2055  location of each decl in the source file as
2056  well as surrounding comments.
2057  --dependency_out=FILE Write a dependency output file in the format
2058  expected by make. This writes the transitive
2059  set of input file paths to FILE
2060  --error_format=FORMAT Set the format in which to print errors.
2061  FORMAT may be 'gcc' (the default) or 'msvs'
2062  (Microsoft Visual Studio format).
2063  --fatal_warnings Make warnings be fatal (similar to -Werr in
2064  gcc). This flag will make protoc return
2065  with a non-zero exit code if any warnings
2066  are generated.
2067  --print_free_field_numbers Print the free field numbers of the messages
2068  defined in the given proto files. Groups share
2069  the same field number space with the parent
2070  message. Extension ranges are counted as
2071  occupied fields numbers.)";
2072  if (!plugin_prefix_.empty()) {
2073  std::cout << R"(
2074  --plugin=EXECUTABLE Specifies a plugin executable to use.
2075  Normally, protoc searches the PATH for
2076  plugins, but you may specify additional
2077  executables not in the path using this flag.
2078  Additionally, EXECUTABLE may be of the form
2079  NAME=PATH, in which case the given plugin name
2080  is mapped to the given executable even if
2081  the executable's own name differs.)";
2082  }
2083 
2085  iter != generators_by_flag_name_.end(); ++iter) {
2086  // FIXME(kenton): If the text is long enough it will wrap, which is ugly,
2087  // but fixing this nicely (e.g. splitting on spaces) is probably more
2088  // trouble than it's worth.
2089  std::cout << std::endl
2090  << " " << iter->first << "=OUT_DIR "
2091  << std::string(19 - iter->first.size(),
2092  ' ') // Spaces for alignment.
2093  << iter->second.help_text;
2094  }
2095  std::cout << R"(
2096  @<filename> Read options and filenames from file. If a
2097  relative file path is specified, the file
2098  will be searched in the working directory.
2099  The --proto_path option will not affect how
2100  this argument file is searched. Content of
2101  the file will be expanded in the position of
2102  @<filename> as in the argument list. Note
2103  that shell expansion is not applied to the
2104  content of the file (i.e., you cannot use
2105  quotes, wildcards, escapes, commands, etc.).
2106  Each line corresponds to a single argument,
2107  even if it contains spaces.)";
2108  std::cout << std::endl;
2109 }
2110 
2112  const std::string& codegen_name, uint64_t supported_features,
2113  const std::vector<const FileDescriptor*>& parsed_files) const {
2114  bool supports_proto3_optional =
2115  supported_features & CodeGenerator::FEATURE_PROTO3_OPTIONAL;
2116  if (!supports_proto3_optional) {
2117  for (const auto fd : parsed_files) {
2118  if (ContainsProto3Optional(fd)) {
2119  std::cerr << fd->name()
2120  << ": is a proto3 file that contains optional fields, but "
2121  "code generator "
2122  << codegen_name
2123  << " hasn't been updated to support optional fields in "
2124  "proto3. Please ask the owner of this code generator to "
2125  "support proto3 optional.";
2126  return false;
2127  }
2128  }
2129  }
2130  return true;
2131 }
2132 
2134  const std::vector<const FileDescriptor*>& parsed_files,
2135  const OutputDirective& output_directive,
2136  GeneratorContext* generator_context) {
2137  // Call the generator.
2139  if (output_directive.generator == NULL) {
2140  // This is a plugin.
2141  GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") &&
2142  HasSuffixString(output_directive.name, "_out"))
2143  << "Bad name for plugin generator: " << output_directive.name;
2144 
2145  std::string plugin_name = PluginName(plugin_prefix_, output_directive.name);
2146  std::string parameters = output_directive.parameter;
2147  if (!plugin_parameters_[plugin_name].empty()) {
2148  if (!parameters.empty()) {
2149  parameters.append(",");
2150  }
2151  parameters.append(plugin_parameters_[plugin_name]);
2152  }
2153  if (!GeneratePluginOutput(parsed_files, plugin_name, parameters,
2154  generator_context, &error)) {
2155  std::cerr << output_directive.name << ": " << error << std::endl;
2156  return false;
2157  }
2158  } else {
2159  // Regular generator.
2160  std::string parameters = output_directive.parameter;
2161  if (!generator_parameters_[output_directive.name].empty()) {
2162  if (!parameters.empty()) {
2163  parameters.append(",");
2164  }
2165  parameters.append(generator_parameters_[output_directive.name]);
2166  }
2168  output_directive.name,
2169  output_directive.generator->GetSupportedFeatures(), parsed_files)) {
2170  return false;
2171  }
2172 
2173  if (!output_directive.generator->GenerateAll(parsed_files, parameters,
2174  generator_context, &error)) {
2175  // Generator returned an error.
2176  std::cerr << output_directive.name << ": " << error << std::endl;
2177  return false;
2178  }
2179  }
2180 
2181  return true;
2182 }
2183 
2185  const std::vector<const FileDescriptor*>& parsed_files,
2186  const GeneratorContextMap& output_directories,
2187  DiskSourceTree* source_tree) {
2188  FileDescriptorSet file_set;
2189 
2190  std::set<const FileDescriptor*> already_seen;
2191  for (int i = 0; i < parsed_files.size(); i++) {
2192  GetTransitiveDependencies(parsed_files[i], false, false, &already_seen,
2193  file_set.mutable_file());
2194  }
2195 
2196  std::vector<std::string> output_filenames;
2197  for (const auto& pair : output_directories) {
2198  const std::string& location = pair.first;
2199  GeneratorContextImpl* directory = pair.second.get();
2200  std::vector<std::string> relative_output_filenames;
2201  directory->GetOutputFilenames(&relative_output_filenames);
2202  for (int i = 0; i < relative_output_filenames.size(); i++) {
2203  std::string output_filename = location + relative_output_filenames[i];
2204  if (output_filename.compare(0, 2, "./") == 0) {
2205  output_filename = output_filename.substr(2);
2206  }
2207  output_filenames.push_back(output_filename);
2208  }
2209  }
2210 
2211  int fd;
2212  do {
2213  fd = open(dependency_out_name_.c_str(),
2214  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
2215  } while (fd < 0 && errno == EINTR);
2216 
2217  if (fd < 0) {
2218  perror(dependency_out_name_.c_str());
2219  return false;
2220  }
2221 
2222  io::FileOutputStream out(fd);
2223  io::Printer printer(&out, '$');
2224 
2225  for (int i = 0; i < output_filenames.size(); i++) {
2226  printer.Print(output_filenames[i].c_str());
2227  if (i == output_filenames.size() - 1) {
2228  printer.Print(":");
2229  } else {
2230  printer.Print(" \\\n");
2231  }
2232  }
2233 
2234  for (int i = 0; i < file_set.file_size(); i++) {
2235  const FileDescriptorProto& file = file_set.file(i);
2236  const std::string& virtual_file = file.name();
2237  std::string disk_file;
2238  if (source_tree &&
2239  source_tree->VirtualFileToDiskFile(virtual_file, &disk_file)) {
2240  printer.Print(" $disk_file$", "disk_file", disk_file);
2241  if (i < file_set.file_size() - 1) printer.Print("\\\n");
2242  } else {
2243  std::cerr << "Unable to identify path for file " << virtual_file
2244  << std::endl;
2245  return false;
2246  }
2247  }
2248 
2249  return true;
2250 }
2251 
2253  const std::vector<const FileDescriptor*>& parsed_files,
2254  const std::string& plugin_name, const std::string& parameter,
2255  GeneratorContext* generator_context, std::string* error) {
2256  CodeGeneratorRequest request;
2257  CodeGeneratorResponse response;
2258  std::string processed_parameter = parameter;
2259 
2260 
2261  // Build the request.
2262  if (!processed_parameter.empty()) {
2263  request.set_parameter(processed_parameter);
2264  }
2265 
2266 
2267  std::set<const FileDescriptor*> already_seen;
2268  for (int i = 0; i < parsed_files.size(); i++) {
2269  request.add_file_to_generate(parsed_files[i]->name());
2270  GetTransitiveDependencies(parsed_files[i],
2271  true, // Include json_name for plugins.
2272  true, // Include source code info.
2273  &already_seen, request.mutable_proto_file());
2274  }
2275 
2277  request.mutable_compiler_version();
2278  version->set_major(PROTOBUF_VERSION / 1000000);
2279  version->set_minor(PROTOBUF_VERSION / 1000 % 1000);
2280  version->set_patch(PROTOBUF_VERSION % 1000);
2281  version->set_suffix(PROTOBUF_VERSION_SUFFIX);
2282 
2283  // Invoke the plugin.
2284  Subprocess subprocess;
2285 
2286  if (plugins_.count(plugin_name) > 0) {
2287  subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME);
2288  } else {
2289  subprocess.Start(plugin_name, Subprocess::SEARCH_PATH);
2290  }
2291 
2292  std::string communicate_error;
2293  if (!subprocess.Communicate(request, &response, &communicate_error)) {
2294  *error = strings::Substitute("$0: $1", plugin_name, communicate_error);
2295  return false;
2296  }
2297 
2298  // Write the files. We do this even if there was a generator error in order
2299  // to match the behavior of a compiled-in generator.
2300  std::unique_ptr<io::ZeroCopyOutputStream> current_output;
2301  for (int i = 0; i < response.file_size(); i++) {
2302  const CodeGeneratorResponse::File& output_file = response.file(i);
2303 
2304  if (!output_file.insertion_point().empty()) {
2305  std::string filename = output_file.name();
2306  // Open a file for insert.
2307  // We reset current_output to NULL first so that the old file is closed
2308  // before the new one is opened.
2309  current_output.reset();
2310  current_output.reset(
2311  generator_context->OpenForInsertWithGeneratedCodeInfo(
2312  filename, output_file.insertion_point(),
2313  output_file.generated_code_info()));
2314  } else if (!output_file.name().empty()) {
2315  // Starting a new file. Open it.
2316  // We reset current_output to NULL first so that the old file is closed
2317  // before the new one is opened.
2318  current_output.reset();
2319  current_output.reset(generator_context->Open(output_file.name()));
2320  } else if (current_output == NULL) {
2322  "$0: First file chunk returned by plugin did not specify a file "
2323  "name.",
2324  plugin_name);
2325  return false;
2326  }
2327 
2328  // Use CodedOutputStream for convenience; otherwise we'd need to provide
2329  // our own buffer-copying loop.
2330  io::CodedOutputStream writer(current_output.get());
2331  writer.WriteString(output_file.content());
2332  }
2333 
2334  // Check for errors.
2335  if (!response.error().empty()) {
2336  // Generator returned an error.
2337  *error = response.error();
2338  return false;
2339  } else if (!EnforceProto3OptionalSupport(
2340  plugin_name, response.supported_features(), parsed_files)) {
2341  return false;
2342  }
2343 
2344  return true;
2345 }
2346 
2348  // Look up the type.
2349  const Descriptor* type = pool->FindMessageTypeByName(codec_type_);
2350  if (type == NULL) {
2351  std::cerr << "Type not defined: " << codec_type_ << std::endl;
2352  return false;
2353  }
2354 
2355  DynamicMessageFactory dynamic_factory(pool);
2356  std::unique_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
2357 
2358  if (mode_ == MODE_ENCODE) {
2359  SetFdToTextMode(STDIN_FILENO);
2360  SetFdToBinaryMode(STDOUT_FILENO);
2361  } else {
2362  SetFdToBinaryMode(STDIN_FILENO);
2363  SetFdToTextMode(STDOUT_FILENO);
2364  }
2365 
2366  io::FileInputStream in(STDIN_FILENO);
2367  io::FileOutputStream out(STDOUT_FILENO);
2368 
2369  if (mode_ == MODE_ENCODE) {
2370  // Input is text.
2371  ErrorPrinter error_collector(error_format_);
2372  TextFormat::Parser parser;
2373  parser.RecordErrorsTo(&error_collector);
2374  parser.AllowPartialMessage(true);
2375 
2376  if (!parser.Parse(&in, message.get())) {
2377  std::cerr << "Failed to parse input." << std::endl;
2378  return false;
2379  }
2380  } else {
2381  // Input is binary.
2382  if (!message->ParsePartialFromZeroCopyStream(&in)) {
2383  std::cerr << "Failed to parse input." << std::endl;
2384  return false;
2385  }
2386  }
2387 
2388  if (!message->IsInitialized()) {
2389  std::cerr << "warning: Input message is missing required fields: "
2390  << message->InitializationErrorString() << std::endl;
2391  }
2392 
2393  if (mode_ == MODE_ENCODE) {
2394  // Output is binary.
2395  io::CodedOutputStream coded_out(&out);
2396  coded_out.SetSerializationDeterministic(deterministic_output_);
2397  if (!message->SerializePartialToCodedStream(&coded_out)) {
2398  std::cerr << "output: I/O error." << std::endl;
2399  return false;
2400  }
2401  } else {
2402  // Output is text.
2403  if (!TextFormat::Print(*message, &out)) {
2404  std::cerr << "output: I/O error." << std::endl;
2405  return false;
2406  }
2407  }
2408 
2409  return true;
2410 }
2411 
2413  const std::vector<const FileDescriptor*>& parsed_files) {
2414  FileDescriptorSet file_set;
2415 
2416  std::set<const FileDescriptor*> already_seen;
2418  // Since we don't want to output transitive dependencies, but we do want
2419  // things to be in dependency order, add all dependencies that aren't in
2420  // parsed_files to already_seen. This will short circuit the recursion
2421  // in GetTransitiveDependencies.
2422  std::set<const FileDescriptor*> to_output;
2423  to_output.insert(parsed_files.begin(), parsed_files.end());
2424  for (int i = 0; i < parsed_files.size(); i++) {
2425  const FileDescriptor* file = parsed_files[i];
2426  for (int j = 0; j < file->dependency_count(); j++) {
2427  const FileDescriptor* dependency = file->dependency(j);
2428  // if the dependency isn't in parsed files, mark it as already seen
2429  if (to_output.find(dependency) == to_output.end()) {
2430  already_seen.insert(dependency);
2431  }
2432  }
2433  }
2434  }
2435  for (int i = 0; i < parsed_files.size(); i++) {
2436  GetTransitiveDependencies(parsed_files[i],
2437  true, // Include json_name
2438  source_info_in_descriptor_set_, &already_seen,
2439  file_set.mutable_file());
2440  }
2441 
2442  int fd;
2443  do {
2444  fd = open(descriptor_set_out_name_.c_str(),
2445  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
2446  } while (fd < 0 && errno == EINTR);
2447 
2448  if (fd < 0) {
2449  perror(descriptor_set_out_name_.c_str());
2450  return false;
2451  }
2452 
2453  io::FileOutputStream out(fd);
2454 
2455  {
2456  io::CodedOutputStream coded_out(&out);
2457  // Determinism is useful here because build outputs are sometimes checked
2458  // into version control.
2459  coded_out.SetSerializationDeterministic(true);
2460  if (!file_set.SerializeToCodedStream(&coded_out)) {
2461  std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno())
2462  << std::endl;
2463  out.Close();
2464  return false;
2465  }
2466  }
2467 
2468  if (!out.Close()) {
2469  std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno())
2470  << std::endl;
2471  return false;
2472  }
2473 
2474  return true;
2475 }
2476 
2478  const FileDescriptor* file, bool include_json_name,
2479  bool include_source_code_info,
2480  std::set<const FileDescriptor*>* already_seen,
2481  RepeatedPtrField<FileDescriptorProto>* output) {
2482  if (!already_seen->insert(file).second) {
2483  // Already saw this file. Skip.
2484  return;
2485  }
2486 
2487  // Add all dependencies.
2488  for (int i = 0; i < file->dependency_count(); i++) {
2489  GetTransitiveDependencies(file->dependency(i), include_json_name,
2490  include_source_code_info, already_seen, output);
2491  }
2492 
2493  // Add this file.
2494  FileDescriptorProto* new_descriptor = output->Add();
2495  file->CopyTo(new_descriptor);
2496  if (include_json_name) {
2497  file->CopyJsonNameTo(new_descriptor);
2498  }
2499  if (include_source_code_info) {
2500  file->CopySourceCodeInfoTo(new_descriptor);
2501  }
2502 }
2503 
2504 namespace {
2505 
2506 // Utility function for PrintFreeFieldNumbers.
2507 // Stores occupied ranges into the ranges parameter, and next level of sub
2508 // message types into the nested_messages parameter. The FieldRange is left
2509 // inclusive, right exclusive. i.e. [a, b).
2510 //
2511 // Nested Messages:
2512 // Note that it only stores the nested message type, iff the nested type is
2513 // either a direct child of the given descriptor, or the nested type is a
2514 // descendant of the given descriptor and all the nodes between the
2515 // nested type and the given descriptor are group types. e.g.
2516 //
2517 // message Foo {
2518 // message Bar {
2519 // message NestedBar {}
2520 // }
2521 // group Baz = 1 {
2522 // group NestedBazGroup = 2 {
2523 // message Quz {
2524 // message NestedQuz {}
2525 // }
2526 // }
2527 // message NestedBaz {}
2528 // }
2529 // }
2530 //
2531 // In this case, Bar, Quz and NestedBaz will be added into the nested types.
2532 // Since free field numbers of group types will not be printed, this makes sure
2533 // the nested message types in groups will not be dropped. The nested_messages
2534 // parameter will contain the direct children (when groups are ignored in the
2535 // tree) of the given descriptor for the caller to traverse. The declaration
2536 // order of the nested messages is also preserved.
2537 typedef std::pair<int, int> FieldRange;
2538 void GatherOccupiedFieldRanges(
2539  const Descriptor* descriptor, std::set<FieldRange>* ranges,
2540  std::vector<const Descriptor*>* nested_messages) {
2541  std::set<const Descriptor*> groups;
2542  for (int i = 0; i < descriptor->field_count(); ++i) {
2543  const FieldDescriptor* fd = descriptor->field(i);
2544  ranges->insert(FieldRange(fd->number(), fd->number() + 1));
2545  if (fd->type() == FieldDescriptor::TYPE_GROUP) {
2546  groups.insert(fd->message_type());
2547  }
2548  }
2549  for (int i = 0; i < descriptor->extension_range_count(); ++i) {
2550  ranges->insert(FieldRange(descriptor->extension_range(i)->start,
2551  descriptor->extension_range(i)->end));
2552  }
2553  for (int i = 0; i < descriptor->reserved_range_count(); ++i) {
2554  ranges->insert(FieldRange(descriptor->reserved_range(i)->start,
2555  descriptor->reserved_range(i)->end));
2556  }
2557  // Handle the nested messages/groups in declaration order to make it
2558  // post-order strict.
2559  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
2560  const Descriptor* nested_desc = descriptor->nested_type(i);
2561  if (groups.find(nested_desc) != groups.end()) {
2562  GatherOccupiedFieldRanges(nested_desc, ranges, nested_messages);
2563  } else {
2564  nested_messages->push_back(nested_desc);
2565  }
2566  }
2567 }
2568 
2569 // Utility function for PrintFreeFieldNumbers.
2570 // Actually prints the formatted free field numbers for given message name and
2571 // occupied ranges.
2572 void FormatFreeFieldNumbers(const std::string& name,
2573  const std::set<FieldRange>& ranges) {
2575  StringAppendF(&output, "%-35s free:", name.c_str());
2576  int next_free_number = 1;
2577  for (std::set<FieldRange>::const_iterator i = ranges.begin();
2578  i != ranges.end(); ++i) {
2579  // This happens when groups re-use parent field numbers, in which
2580  // case we skip the FieldRange entirely.
2581  if (next_free_number >= i->second) continue;
2582 
2583  if (next_free_number < i->first) {
2584  if (next_free_number + 1 == i->first) {
2585  // Singleton
2586  StringAppendF(&output, " %d", next_free_number);
2587  } else {
2588  // Range
2589  StringAppendF(&output, " %d-%d", next_free_number, i->first - 1);
2590  }
2591  }
2592  next_free_number = i->second;
2593  }
2594  if (next_free_number <= FieldDescriptor::kMaxNumber) {
2595  StringAppendF(&output, " %d-INF", next_free_number);
2596  }
2597  std::cout << output << std::endl;
2598 }
2599 
2600 } // namespace
2601 
2603  std::set<FieldRange> ranges;
2604  std::vector<const Descriptor*> nested_messages;
2605  GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages);
2606 
2607  for (int i = 0; i < nested_messages.size(); ++i) {
2608  PrintFreeFieldNumbers(nested_messages[i]);
2609  }
2610  FormatFreeFieldNumbers(descriptor->full_name(), ranges);
2611 }
2612 
2613 
2614 } // namespace compiler
2615 } // namespace protobuf
2616 } // namespace google
FileDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7321
google::protobuf::DescriptorPool::FindFileByName
const FileDescriptor * FindFileByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1369
google::protobuf::compiler::CommandLineInterface::plugin_parameters_
std::map< std::string, std::string > plugin_parameters_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:356
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
google::protobuf::compiler::CommandLineInterface::MODE_DECODE
@ MODE_DECODE
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:370
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::append_mode_
bool append_mode_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:437
filename
const char * filename
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
google::protobuf::DescriptorPool::ClearUnusedImportTrackFiles
void ClearUnusedImportTrackFiles()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1292
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddErrorOrWarning
void AddErrorOrWarning(const std::string &filename, int line, int column, const std::string &message, const std::string &type, std::ostream &out)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:322
regen-readme.it
it
Definition: regen-readme.py:15
http2_test_server.format
format
Definition: http2_test_server.py:118
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
absl::str_format_internal::LengthMod::j
@ j
google::protobuf::compiler::CommandLineInterface::RegisterGenerator
void RegisterGenerator(const std::string &flag_name, CodeGenerator *generator, const std::string &help_text)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:788
google::protobuf::compiler::CommandLineInterface::PRINT_NONE
@ PRINT_NONE
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:377
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
google::protobuf::compiler::CommandLineInterface::descriptor_set_out_name_
std::string descriptor_set_out_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:423
google::protobuf::TextFormat::Print
static bool Print(const Message &message, io::ZeroCopyOutputStream *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/text_format.cc:2385
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::directory_
GeneratorContextImpl * directory_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:429
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::info_to_insert_
google::protobuf::GeneratedCodeInfo info_to_insert_
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:480
metadata
Definition: cq_verifier.cc:48
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
google::protobuf::compiler::CommandLineInterface::deterministic_output_
bool deterministic_output_
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.h:451
element_name
std::string element_name
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3096
google::protobuf::compiler::CommandLineInterface::WriteDescriptorSet
bool WriteDescriptorSet(const std::vector< const FileDescriptor * > &parsed_files)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:2184
google::protobuf::compiler::IsWindowsAbsolutePath
static bool IsWindowsAbsolutePath(const std::string &text)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.cc:73
google::protobuf::compiler::CommandLineInterface::MODE_ENCODE
@ MODE_ENCODE
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:369
false
#define false
Definition: setup_once.h:323
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::inner_
std::unique_ptr< io::StringOutputStream > inner_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:440
write
#define write
Definition: test-fs.c:47
google::protobuf::compiler::DiskSourceTree::CANNOT_OPEN
@ CANNOT_OPEN
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.h:267
google::protobuf::compiler::CommandLineInterface::MakeInputsBeProtoPathRelative
bool MakeInputsBeProtoPathRelative(DiskSourceTree *source_tree, DescriptorDatabase *fallback_database)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1208
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::BackUp
void BackUp(int count) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:443
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddWarning
void AddWarning(const std::string &filename, int line, int column, const std::string &message) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:306
google::protobuf::compiler::CommandLineInterface::MODE_PRINT
@ MODE_PRINT
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:371
GOOGLE_DCHECK
#define GOOGLE_DCHECK
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:194
google::protobuf.internal._parameterized.parameters
def parameters(*testcases)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/_parameterized.py:315
grpc::protobuf::MergedDescriptorDatabase
GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase
Definition: config_grpc_cli.h:57
google::protobuf::compiler::CommandLineInterface::source_info_in_descriptor_set_
bool source_info_in_descriptor_set_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:436
benchmark.request
request
Definition: benchmark.py:77
Subprocess
Definition: memory_usage_test.cc:39
google::protobuf::compiler::CommandLineInterface::PRINT_FREE_FIELDS
@ PRINT_FREE_FIELDS
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:378
FileDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:128
metadata
struct metadata metadata
GOOGLE_CHECK_EQ
#define GOOGLE_CHECK_EQ(A, B)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:156
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddError
void AddError(const std::string &filename, int line, int column, const std::string &message)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:286
error
grpc_error_handle error
Definition: retry_filter.cc:499
google::protobuf::compiler::CommandLineInterface::EncodeOrDecode
bool EncodeOrDecode(const DescriptorPool *pool)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:2121
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:365
google::protobuf::compiler::CommandLineInterface::plugin_prefix_
std::string plugin_prefix_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:359
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::parsed_files_
const std::vector< const FileDescriptor * > & parsed_files_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:399
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
grpc::protobuf::io::Printer
GRPC_CUSTOM_PRINTER Printer
Definition: src/compiler/config.h:54
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
grpc::protobuf::DynamicMessageFactory
GRPC_CUSTOM_DYNAMICMESSAGEFACTORY DynamicMessageFactory
Definition: config_grpc_cli.h:54
files_
std::map< std::string, std::unique_ptr< std::string > > files_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc:123
google::protobuf::compiler::CommandLineInterface::PrintFreeFieldNumbers
void PrintFreeFieldNumbers(const Descriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:2366
FileDescriptorProto::service_size
int service_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7745
status
absl::Status status
Definition: rls.cc:251
setup.name
name
Definition: setup.py:542
grpc::protobuf::io::ZeroCopyOutputStream
GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream
Definition: include/grpcpp/impl/codegen/config_protobuf.h:100
google::protobuf::compiler::CommandLineInterface::InterpretArgument
ParseArgumentStatus InterpretArgument(const std::string &name, const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1423
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::ByteCount
int64_t ByteCount() const override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:444
google::protobuf::compiler::DiskSourceTree
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.h:240
version
Definition: version.py:1
grpc::protobuf::DescriptorPool
GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool
Definition: include/grpcpp/impl/codegen/config_protobuf.h:82
check_documentation.path
path
Definition: check_documentation.py:57
grpc::Version
std::string Version()
Return gRPC library version.
Definition: version_cc.cc:28
google::protobuf::compiler::CommandLineInterface::codec_type_
std::string codec_type_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:415
google::protobuf::compiler::CommandLineInterface::output_directives_
std::vector< OutputDirective > output_directives_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:411
grpc::protobuf::compiler::DiskSourceTree
GRPC_CUSTOM_DISKSOURCETREE DiskSourceTree
Definition: config_grpc_cli.h:62
second
StrT second
Definition: cxa_demangle.cpp:4885
env.new
def new
Definition: env.py:51
google::protobuf::compiler::CommandLineInterface::imports_in_descriptor_set_
bool imports_in_descriptor_set_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:432
google::protobuf::FieldDescriptor::TYPE_GROUP
@ TYPE_GROUP
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:535
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddWarning
void AddWarning(const std::string &filename, const std::string &element_name, const Message *descriptor, ErrorLocation location, const std::string &message) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:328
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::Next
bool Next(void **data, int *size) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:440
google::protobuf::compiler::CommandLineInterface::GeneratePluginOutput
bool GeneratePluginOutput(const std::vector< const FileDescriptor * > &parsed_files, const std::string &plugin_name, const std::string &parameter, GeneratorContext *generator_context, std::string *error)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:2031
iterator
const typedef MCPhysReg * iterator
Definition: MCRegisterInfo.h:27
google::protobuf::compiler::CommandLineInterface::Run
int Run(int argc, const char *const argv[])
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:814
google::protobuf::StringAppendF
void StringAppendF(string *dst, const char *format,...)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringprintf.cc:127
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::UpdateMetadata
void UpdateMetadata(size_t insertion_offset, size_t insertion_length)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:615
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
FileDescriptorSet::file
const PROTOBUF_NAMESPACE_ID::FileDescriptorProto & file(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7288
grpc::protobuf::SimpleDescriptorDatabase
GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase
Definition: include/grpcpp/impl/codegen/config_protobuf.h:89
Descriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:121
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::FoundErrors
bool FoundErrors() const
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:334
google::protobuf::compiler::CommandLineInterface::PARSE_ARGUMENT_FAIL
@ PARSE_ARGUMENT_FAIL
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:233
google::protobuf::compiler::CommandLineInterface::CommandLineInterface
CommandLineInterface()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:775
google::protobuf::compiler::CommandLineInterface::GeneratorContextMap
std::unordered_map< std::string, std::unique_ptr< GeneratorContextImpl > > GeneratorContextMap
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:210
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
google::protobuf::compiler::CommandLineInterface::disallow_services_
bool disallow_services_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:439
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::data_
std::string data_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:434
google::protobuf::compiler::CommandLineInterface::PARSE_ARGUMENT_DONE_AND_EXIT
@ PARSE_ARGUMENT_DONE_AND_EXIT
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:232
google::protobuf::FileDescriptor::SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1394
grpc::protobuf::io::StringOutputStream
GRPC_CUSTOM_STRINGOUTPUTSTREAM StringOutputStream
Definition: src/compiler/config.h:56
FieldDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:133
grpc::protobuf::compiler::GeneratorContext
GRPC_CUSTOM_GENERATORCONTEXT GeneratorContext
Definition: src/compiler/config.h:42
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
google::protobuf::compiler::CommandLineInterface::PARSE_ARGUMENT_DONE_AND_CONTINUE
@ PARSE_ARGUMENT_DONE_AND_CONTINUE
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:231
google::protobuf::compiler::CommandLineInterface::direct_dependencies_
std::set< std::string > direct_dependencies_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:396
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::tree_
DiskSourceTree * tree_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:357
grpc::protobuf::compiler::CodeGenerator
GRPC_CUSTOM_CODEGENERATOR CodeGenerator
Definition: src/compiler/config.h:41
asyncio_get_stats.parser
parser
Definition: asyncio_get_stats.py:34
gen_server_registered_method_bad_client_test_body.text
def text
Definition: gen_server_registered_method_bad_client_test_body.py:50
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
grpc_version.PROTOBUF_VERSION
string PROTOBUF_VERSION
Definition: tools/distrib/python/grpc_version.py:18
google::protobuf::compiler::CommandLineInterface::kPathSeparator
static const char *const kPathSeparator
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:111
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
google::protobuf::compiler::CommandLineInterface::descriptor_set_in_names_
std::vector< std::string > descriptor_set_in_names_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:419
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
google::protobuf::compiler::CommandLineInterface::plugins_
std::map< std::string, std::string > plugins_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:364
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::found_warnings_
bool found_warnings_
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:376
google::protobuf::compiler::CommandLineInterface::mode_
Mode mode_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:374
google::protobuf::compiler::CommandLineInterface::version_info_
std::string version_info_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:338
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::Open
io::ZeroCopyOutputStream * Open(const std::string &filename)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:580
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::files_
std::map< std::string, std::string > files_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:398
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::ErrorPrinter
ErrorPrinter(ErrorFormat format, DiskSourceTree *tree=NULL)
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:292
google::protobuf::compiler::CommandLineInterface::print_mode_
PrintMode print_mode_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:381
google::protobuf::compiler::CommandLineInterface::error_format_
ErrorFormat error_format_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:388
google::protobuf::compiler::CommandLineInterface::dependency_out_name_
std::string dependency_out_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:427
google::protobuf::compiler::CommandLineInterface::fatal_warnings_
bool fatal_warnings_
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.h:397
google::protobuf::TextFormat::ParseFromString
static bool ParseFromString(const std::string &input, Message *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/text_format.cc:1485
argument
Definition: third_party/boringssl-with-bazel/src/tool/internal.h:108
GeneratedCodeInfo_Annotation
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:6853
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation
ErrorLocation
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1638
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::WriteAllToDisk
bool WriteAllToDisk(const std::string &prefix)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:449
google::protobuf::compiler::DiskSourceTree::SHADOWED
@ SHADOWED
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.h:266
google::protobuf::compiler::CommandLineInterface::VerifyInputFilesInDescriptors
bool VerifyInputFilesInDescriptors(DescriptorDatabase *fallback_database)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1042
google::protobuf::DescriptorPool
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1539
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddError
void AddError(int line, int column, const std::string &message) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:313
arg
Definition: cmdline.cc:40
google::protobuf::compiler::CommandLineInterface::MODE_COMPILE
@ MODE_COMPILE
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:368
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddError
void AddError(const std::string &filename, int line, int column, const std::string &message) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:300
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::InsertShiftedInfo
void InsertShiftedInfo(const std::string &insertion_content, size_t insertion_offset, size_t indent_length, google::protobuf::GeneratedCodeInfo &target_info)
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:673
database
database
Definition: benchmark/.ycm_extra_conf.py:35
close
#define close
Definition: test-fs.c:48
google::protobuf::compiler::CommandLineInterface::generator_parameters_
std::map< std::string, std::string > generator_parameters_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:354
generate_copts.relative_filename
def relative_filename(filename)
Definition: abseil-cpp/absl/copts/generate_copts.py:27
google::protobuf::compiler::CommandLineInterface::ERROR_FORMAT_GCC
@ ERROR_FORMAT_GCC
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:384
io
indent_
int indent_
Definition: json_writer.cc:72
google::protobuf::WARNING
static const LogLevel WARNING
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:71
grpc::protobuf::DescriptorDatabase
GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase
Definition: include/grpcpp/impl/codegen/config_protobuf.h:83
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
google::protobuf::compiler::CommandLineInterface::ParseArgumentStatus
ParseArgumentStatus
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:230
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::ListParsedFiles
void ListParsedFiles(std::vector< const FileDescriptor * > *output) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:410
google::protobuf::strings::Substitute
string Substitute(const char *format, const SubstituteArg &arg0, const SubstituteArg &arg1, const SubstituteArg &arg2, const SubstituteArg &arg3, const SubstituteArg &arg4, const SubstituteArg &arg5, const SubstituteArg &arg6, const SubstituteArg &arg7, const SubstituteArg &arg8, const SubstituteArg &arg9)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/substitute.cc:55
grpc::protobuf::io::CodedOutputStream
GRPC_CUSTOM_CODEDOUTPUTSTREAM CodedOutputStream
Definition: src/compiler/config.h:55
grpc::protobuf::compiler::MultiFileErrorCollector
GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR MultiFileErrorCollector
Definition: config_grpc_cli.h:64
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::filename_
std::string filename_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:430
google::protobuf::string_as_array
char * string_as_array(string *str)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stl_util.h:63
FileDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:501
google::protobuf::compiler::CommandLineInterface::GetTransitiveDependencies
static void GetTransitiveDependencies(const FileDescriptor *file, bool include_json_name, bool include_source_code_info, std::set< const FileDescriptor * > *already_seen, RepeatedPtrField< FileDescriptorProto > *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:2241
google::protobuf::compiler::Subprocess::EXACT_NAME
@ EXACT_NAME
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/compiler/subprocess.h:64
google::protobuf::HasPrefixString
bool HasPrefixString(const string &str, const string &prefix)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:115
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::format_
const ErrorFormat format_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:356
google::protobuf::compiler::CommandLineInterface::executable_name_
std::string executable_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:335
FileDescriptorSet
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:333
google::protobuf::ERROR
static const LogLevel ERROR
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:70
google::protobuf::compiler::CommandLineInterface::~CommandLineInterface
~CommandLineInterface()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:786
google::protobuf::DescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:71
google::protobuf::compiler::CommandLineInterface::ErrorFormat
ErrorFormat
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:383
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
writer
void writer(void *n)
Definition: libuv/docs/code/locks/main.c:22
google::protobuf::compiler::cpp::FieldRange
FieldRangeImpl< T > FieldRange(const T *desc)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h:791
google::protobuf::compiler::DiskSourceTree::SUCCESS
@ SUCCESS
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.h:265
google::protobuf::compiler::CommandLineInterface::GenerateDependencyManifestFile
bool GenerateDependencyManifestFile(const std::vector< const FileDescriptor * > &parsed_files, const GeneratorContextMap &output_directories, DiskSourceTree *source_tree)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1963
FileDescriptorSet::mutable_file
PROTOBUF_NAMESPACE_ID::FileDescriptorProto * mutable_file(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7276
google::protobuf::compiler::CommandLineInterface::ExpandArgumentFile
bool ExpandArgumentFile(const std::string &file, std::vector< std::string > *arguments)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1221
FATAL
#define FATAL(msg)
Definition: task.h:88
google::protobuf::FileDescriptor::name
const std::string & name() const
FileDescriptorSet::file_size
int file_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7270
google::protobuf::compiler::CommandLineInterface::ParseArguments
ParseArgumentStatus ParseArguments(int argc, const char *const argv[])
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1237
google::protobuf::Message
Definition: bloaty/third_party/protobuf/src/google/protobuf/message.h:205
google::protobuf.internal::VersionString
string VersionString(int version)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/common.cc:98
google::protobuf::compiler::DiskSourceTree::NO_MAPPING
@ NO_MAPPING
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.h:268
make_dist_html.groups
list groups
Definition: make_dist_html.py:120
google::protobuf::FieldDescriptor::kMaxNumber
static const int kMaxNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:581
GeneratedCodeInfo_Annotation::set_end
void set_end(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13921
regress.directory
directory
Definition: regress/regress.py:17
google::protobuf::StringReplace
void StringReplace(const string &s, const string &oldsub, const string &newsub, bool replace_all, string *res)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:148
google::protobuf::compiler::Subprocess::SEARCH_PATH
@ SEARCH_PATH
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/compiler/subprocess.h:63
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
google::protobuf::compiler::CommandLineInterface::MakeProtoProtoPathRelative
bool MakeProtoProtoPathRelative(DiskSourceTree *source_tree, std::string *proto, DescriptorDatabase *fallback_database)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1140
google::protobuf::compiler::CommandLineInterface::generators_by_flag_name_
GeneratorMap generators_by_flag_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:348
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl
GeneratorContextImpl(const std::vector< const FileDescriptor * > &parsed_files)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:445
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:403
GeneratedCodeInfo::add_annotation
PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation * add_annotation()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13959
google::protobuf::compiler::CommandLineInterface::EnforceProto3OptionalSupport
bool EnforceProto3OptionalSupport(const std::string &codegen_name, uint64_t supported_features, const std::vector< const FileDescriptor * > &parsed_files) const
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:2029
google::protobuf::compiler::CodeGenerator::FEATURE_PROTO3_OPTIONAL
@ FEATURE_PROTO3_OPTIONAL
Definition: protobuf/src/google/protobuf/compiler/code_generator.h:109
google::protobuf::FileDescriptor::dependency
const FileDescriptor * dependency(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7235
F_OK
#define F_OK
Definition: win.h:655
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::~ErrorPrinter
~ErrorPrinter()
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:297
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::AddJarManifest
void AddJarManifest()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:563
google::protobuf::TextFormat::PrintToString
static bool PrintToString(const Message &message, std::string *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/text_format.cc:2395
google::protobuf::FileDescriptor::service_count
int service_count() const
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
google::protobuf::compiler::CommandLineInterface::AllowPlugins
void AllowPlugins(const std::string &exe_name_prefix)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:810
first
StrT first
Definition: cxa_demangle.cpp:4884
google::protobuf::io::ZeroCopyOutputStream
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h:183
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
regen-readme.line
line
Definition: regen-readme.py:30
google::protobuf::compiler::CommandLineInterface::Clear
void Clear()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1117
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::WriteAllToZip
bool WriteAllToZip(const std::string &filename)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:523
google::protobuf::Split
std::vector< string > Split(const string &full, const char *delim, bool skip_empty=true)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:235
arg
struct arg arg
GOOGLE_CHECK
#define GOOGLE_CHECK(EXPRESSION)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:153
google::protobuf::compiler::CommandLineInterface::direct_dependencies_explicitly_set_
bool direct_dependencies_explicitly_set_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:397
data_
std::string data_
Definition: cord_rep_btree_navigator_test.cc:84
desc
#define desc
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:338
GeneratedCodeInfo_Annotation::end
::PROTOBUF_NAMESPACE_ID::int32 end() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13913
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddWarning
void AddWarning(int line, int column, const std::string &message) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:317
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::OpenForInsertWithGeneratedCodeInfo
io::ZeroCopyOutputStream * OpenForInsertWithGeneratedCodeInfo(const std::string &filename, const std::string &insertion_point, const google::protobuf::GeneratedCodeInfo &info) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:640
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
google::protobuf::compiler::CommandLineInterface::PrintHelpText
void PrintHelpText()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1760
google::protobuf::FileDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1320
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::GetOutputFilenames
void GetOutputFilenames(std::vector< std::string > *output_filenames)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:573
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::found_errors_
bool found_errors_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:358
open
#define open
Definition: test-fs.c:46
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::AddError
void AddError(const std::string &filename, const std::string &element_name, const Message *descriptor, ErrorLocation location, const std::string &message) override
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:322
google::protobuf::compiler::CommandLineInterface::ParseInputFiles
bool ParseInputFiles(DescriptorPool *descriptor_pool, std::vector< const FileDescriptor * > *parsed_files)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1063
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::MemoryOutputStream
MemoryOutputStream(GeneratorContextImpl *directory, const std::string &filename, bool append_mode)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:599
iter
Definition: test_winkernel.cpp:47
google::protobuf::HasSuffixString
bool HasSuffixString(const string &str, const string &suffix)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:137
google::protobuf::DescriptorDatabase::FindFileByName
virtual bool FindFileByName(const std::string &filename, FileDescriptorProto *output)=0
GeneratedCodeInfo_Annotation::set_begin
void set_begin(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13893
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::OpenForAppend
io::ZeroCopyOutputStream * OpenForAppend(const std::string &filename)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:586
google::protobuf::compiler::CommandLineInterface::ErrorPrinter::FoundWarnings
bool FoundWarnings() const
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:336
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
google::protobuf::compiler::CommandLineInterface::direct_dependencies_violation_msg_
std::string direct_dependencies_violation_msg_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:401
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
google::protobuf::compiler::CommandLineInterface::generators_by_option_name_
GeneratorMap generators_by_option_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:349
google::protobuf::compiler::CommandLineInterface::ERROR_FORMAT_MSVS
@ ERROR_FORMAT_MSVS
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:385
file::name
char * name
Definition: bloaty/third_party/zlib/examples/gzappend.c:176
google::protobuf::compiler::CommandLineInterface::input_files_
std::vector< std::string > input_files_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:392
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
google::protobuf::compiler::CommandLineInterface::GenerateOutput
bool GenerateOutput(const std::vector< const FileDescriptor * > &parsed_files, const OutputDirective &output_directive, GeneratorContext *generator_context)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1918
GeneratedCodeInfo
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7087
DescriptorPool
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:110
access
Definition: bloaty/third_party/zlib/examples/zran.c:75
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::insertion_point_
std::string insertion_point_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:431
google::protobuf::compiler::GeneratorContext
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/code_generator.h:119
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:146
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::had_error_
bool had_error_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:400
google::protobuf::compiler::CommandLineInterface::GeneratorContextImpl::OpenForInsert
io::ZeroCopyOutputStream * OpenForInsert(const std::string &filename, const std::string &insertion_point)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:592
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
pair
std::pair< std::string, std::string > pair
Definition: abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc:78
google::protobuf::FindOrNull
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/map_util.h:137
google::protobuf::compiler::CommandLineInterface::proto_path_
std::vector< std::pair< std::string, std::string > > proto_path_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h:391
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179
compiler
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc:21
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
google::protobuf::compiler::DiskSourceTree::VirtualFileToDiskFile
bool VirtualFileToDiskFile(const std::string &virtual_file, std::string *disk_file)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer.cc:438
errno.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
google::protobuf::compiler::CommandLineInterface::InitializeDiskSourceTree
bool InitializeDiskSourceTree(DiskSourceTree *source_tree, DescriptorDatabase *fallback_database)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:983
google::protobuf::FileDescriptor::dependency_count
int dependency_count() const
google::protobuf::compiler::CommandLineInterface::MemoryOutputStream::~MemoryOutputStream
virtual ~MemoryOutputStream()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:652
google::protobuf::compiler::CommandLineInterface::ParseArgument
bool ParseArgument(const char *arg, std::string *name, std::string *value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc:1364
google::protobuf::DescriptorPool::AddUnusedImportTrackFile
void AddUnusedImportTrackFile(const std::string &file_name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1288
GeneratedCodeInfo_Annotation::begin
::PROTOBUF_NAMESPACE_ID::int32 begin() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13885
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
O_BINARY
#define O_BINARY
Definition: protobuf/src/google/protobuf/compiler/command_line_interface.cc:100


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:59