objectivec_generator.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. #include <iostream>
  31. #include <google/protobuf/compiler/objectivec/objectivec_generator.h>
  32. #include <google/protobuf/compiler/objectivec/objectivec_file.h>
  33. #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
  34. #include <google/protobuf/io/printer.h>
  35. #include <google/protobuf/io/zero_copy_stream.h>
  36. #include <google/protobuf/stubs/strutil.h>
  37. namespace google {
  38. namespace protobuf {
  39. namespace compiler {
  40. namespace objectivec {
  41. ObjectiveCGenerator::ObjectiveCGenerator() {}
  42. ObjectiveCGenerator::~ObjectiveCGenerator() {}
  43. bool ObjectiveCGenerator::HasGenerateAll() const {
  44. return true;
  45. }
  46. bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
  47. const string& parameter,
  48. GeneratorContext* context,
  49. string* error) const {
  50. *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
  51. return false;
  52. }
  53. bool ObjectiveCGenerator::GenerateAll(const std::vector<const FileDescriptor*>& files,
  54. const string& parameter,
  55. GeneratorContext* context,
  56. string* error) const {
  57. // -----------------------------------------------------------------
  58. // Parse generator options. These options are passed to the compiler using the
  59. // --objc_opt flag. The options are passed as a comma separated list of
  60. // options along with their values. If the option appears multiple times, only
  61. // the last value will be considered.
  62. //
  63. // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework
  64. Options generation_options;
  65. std::vector<std::pair<string, string> > options;
  66. ParseGeneratorParameter(parameter, &options);
  67. for (int i = 0; i < options.size(); i++) {
  68. if (options[i].first == "expected_prefixes_path") {
  69. // Path to find a file containing the expected prefixes
  70. // (objc_class_prefix "PREFIX") for proto packages (package NAME). The
  71. // generator will then issue warnings/errors if in the proto files being
  72. // generated the option is not listed/wrong/etc in the file.
  73. //
  74. // The format of the file is:
  75. // - An entry is a line of "package=prefix".
  76. // - Comments start with "#".
  77. // - A comment can go on a line after a expected package/prefix pair.
  78. // (i.e. - "package=prefix # comment")
  79. //
  80. // There is no validation that the prefixes are good prefixes, it is
  81. // assumed that they are when you create the file.
  82. generation_options.expected_prefixes_path = options[i].second;
  83. } else if (options[i].first == "generate_for_named_framework") {
  84. // The name of the framework that protos are being generated for. This
  85. // will cause the #import statements to be framework based using this
  86. // name (i.e. - "#import <NAME/proto.pbobjc.h>).
  87. //
  88. // NOTE: If this option is used with
  89. // named_framework_to_proto_path_mappings_path, then this is effectively
  90. // the "default" framework name used for everything that wasn't mapped by
  91. // the mapping file.
  92. generation_options.generate_for_named_framework = options[i].second;
  93. } else if (options[i].first == "named_framework_to_proto_path_mappings_path") {
  94. // Path to find a file containing the list of framework names and proto
  95. // files. The generator uses this to decide if a proto file
  96. // referenced should use a framework style import vs. a user level import
  97. // (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h").
  98. //
  99. // The format of the file is:
  100. // - An entry is a line of "frameworkName: file.proto, dir/file2.proto".
  101. // - Comments start with "#".
  102. // - A comment can go on a line after a expected package/prefix pair.
  103. // (i.e. - "frameworkName: file.proto # comment")
  104. //
  105. // Any number of files can be listed for a framework, just separate them
  106. // with commas.
  107. //
  108. // There can be multiple lines listing the same frameworkName incase it
  109. // has a lot of proto files included in it; having multiple lines makes
  110. // things easier to read. If a proto file is not configured in the
  111. // mappings file, it will use the default framework name if one was passed
  112. // with generate_for_named_framework, or the relative path to it's include
  113. // path otherwise.
  114. generation_options.named_framework_to_proto_path_mappings_path = options[i].second;
  115. } else {
  116. *error = "error: Unknown generator option: " + options[i].first;
  117. return false;
  118. }
  119. }
  120. // -----------------------------------------------------------------
  121. // Validate the objc prefix/package pairings.
  122. if (!ValidateObjCClassPrefixes(files, generation_options, error)) {
  123. // *error will have been filled in.
  124. return false;
  125. }
  126. for (int i = 0; i < files.size(); i++) {
  127. const FileDescriptor* file = files[i];
  128. FileGenerator file_generator(file, generation_options);
  129. string filepath = FilePath(file);
  130. // Generate header.
  131. {
  132. std::unique_ptr<io::ZeroCopyOutputStream> output(
  133. context->Open(filepath + ".pbobjc.h"));
  134. io::Printer printer(output.get(), '$');
  135. file_generator.GenerateHeader(&printer);
  136. }
  137. // Generate m file.
  138. {
  139. std::unique_ptr<io::ZeroCopyOutputStream> output(
  140. context->Open(filepath + ".pbobjc.m"));
  141. io::Printer printer(output.get(), '$');
  142. file_generator.GenerateSource(&printer);
  143. }
  144. }
  145. return true;
  146. }
  147. } // namespace objectivec
  148. } // namespace compiler
  149. } // namespace protobuf
  150. } // namespace google