js_generator.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. // Generates JavaScript code for a given .proto file.
  31. //
  32. #ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
  33. #define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
  34. #include <string>
  35. #include <set>
  36. #include <google/protobuf/stubs/logging.h>
  37. #include <google/protobuf/stubs/common.h>
  38. #include <google/protobuf/compiler/code_generator.h>
  39. namespace google {
  40. namespace protobuf {
  41. class Descriptor;
  42. class EnumDescriptor;
  43. class FieldDescriptor;
  44. class OneofDescriptor;
  45. class FileDescriptor;
  46. namespace io { class Printer; }
  47. namespace compiler {
  48. namespace js {
  49. struct GeneratorOptions {
  50. // Output path.
  51. string output_dir;
  52. // Namespace prefix.
  53. string namespace_prefix;
  54. // Enable binary-format support?
  55. bool binary;
  56. // What style of imports should be used.
  57. enum ImportStyle {
  58. kImportClosure, // goog.require()
  59. kImportCommonJs, // require()
  60. kImportBrowser, // no import statements
  61. kImportEs6, // import { member } from ''
  62. } import_style;
  63. GeneratorOptions()
  64. : output_dir("."),
  65. namespace_prefix(""),
  66. binary(false),
  67. import_style(kImportClosure),
  68. add_require_for_enums(false),
  69. testonly(false),
  70. library(""),
  71. error_on_name_conflict(false),
  72. extension(".js"),
  73. one_output_file_per_input_file(false),
  74. annotate_code(false) {}
  75. bool ParseFromOptions(
  76. const std::vector< std::pair< string, string > >& options,
  77. string* error);
  78. // Returns the file name extension to use for generated code.
  79. string GetFileNameExtension() const {
  80. return import_style == kImportClosure ? extension : "_pb.js";
  81. }
  82. enum OutputMode {
  83. // Create an output file for each input .proto file.
  84. kOneOutputFilePerInputFile,
  85. // Create an output file for each type.
  86. kOneOutputFilePerType,
  87. // Put everything in a single file named by the library option.
  88. kEverythingInOneFile,
  89. };
  90. // Indicates how to output the generated code based on the provided options.
  91. OutputMode output_mode() const;
  92. // The remaining options are only relevant when we are using kImportClosure.
  93. // Add a `goog.requires()` call for each enum type used. If not set, a
  94. // forward declaration with `goog.forwardDeclare` is produced instead.
  95. bool add_require_for_enums;
  96. // Set this as a test-only module via `goog.setTestOnly();`.
  97. bool testonly;
  98. // Create a library with name <name>_lib.js rather than a separate .js file
  99. // per type?
  100. string library;
  101. // Error if there are two types that would generate the same output file?
  102. bool error_on_name_conflict;
  103. // The extension to use for output file names.
  104. string extension;
  105. // Create a separate output file for each input file?
  106. bool one_output_file_per_input_file;
  107. // If true, we should build .meta files that contain annotations for
  108. // generated code. See GeneratedCodeInfo in descriptor.proto.
  109. bool annotate_code;
  110. };
  111. // CodeGenerator implementation which generates a JavaScript source file and
  112. // header. If you create your own protocol compiler binary and you want it to
  113. // support JavaScript output, you can do so by registering an instance of this
  114. // CodeGenerator with the CommandLineInterface in your main() function.
  115. class LIBPROTOC_EXPORT Generator : public CodeGenerator {
  116. public:
  117. Generator() {}
  118. virtual ~Generator() {}
  119. virtual bool Generate(const FileDescriptor* file,
  120. const string& parameter,
  121. GeneratorContext* context,
  122. string* error) const {
  123. *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
  124. return false;
  125. }
  126. virtual bool HasGenerateAll() const { return true; }
  127. virtual bool GenerateAll(const std::vector<const FileDescriptor*>& files,
  128. const string& parameter,
  129. GeneratorContext* context,
  130. string* error) const;
  131. private:
  132. void GenerateHeader(const GeneratorOptions& options,
  133. io::Printer* printer) const;
  134. // Generate goog.provides() calls.
  135. void FindProvides(const GeneratorOptions& options,
  136. io::Printer* printer,
  137. const std::vector<const FileDescriptor*>& file,
  138. std::set<string>* provided) const;
  139. void FindProvidesForFile(const GeneratorOptions& options,
  140. io::Printer* printer,
  141. const FileDescriptor* file,
  142. std::set<string>* provided) const;
  143. void FindProvidesForMessage(const GeneratorOptions& options,
  144. io::Printer* printer,
  145. const Descriptor* desc,
  146. std::set<string>* provided) const;
  147. void FindProvidesForEnum(const GeneratorOptions& options,
  148. io::Printer* printer,
  149. const EnumDescriptor* enumdesc,
  150. std::set<string>* provided) const;
  151. // For extension fields at file scope.
  152. void FindProvidesForFields(const GeneratorOptions& options,
  153. io::Printer* printer,
  154. const std::vector<const FieldDescriptor*>& fields,
  155. std::set<string>* provided) const;
  156. // Print the goog.provides() found by the methods above.
  157. void GenerateProvides(const GeneratorOptions& options,
  158. io::Printer* printer,
  159. std::set<string>* provided) const;
  160. // Generate goog.setTestOnly() if indicated.
  161. void GenerateTestOnly(const GeneratorOptions& options,
  162. io::Printer* printer) const;
  163. // Generate goog.requires() calls.
  164. void GenerateRequiresForLibrary(
  165. const GeneratorOptions& options, io::Printer* printer,
  166. const std::vector<const FileDescriptor*>& files,
  167. std::set<string>* provided) const;
  168. void GenerateRequiresForMessage(const GeneratorOptions& options,
  169. io::Printer* printer,
  170. const Descriptor* desc,
  171. std::set<string>* provided) const;
  172. // For extension fields at file scope.
  173. void GenerateRequiresForExtensions(
  174. const GeneratorOptions& options, io::Printer* printer,
  175. const std::vector<const FieldDescriptor*>& fields,
  176. std::set<string>* provided) const;
  177. void GenerateRequiresImpl(const GeneratorOptions& options,
  178. io::Printer* printer, std::set<string>* required,
  179. std::set<string>* forwards,
  180. std::set<string>* provided, bool require_jspb,
  181. bool require_extension, bool require_map) const;
  182. void FindRequiresForMessage(const GeneratorOptions& options,
  183. const Descriptor* desc,
  184. std::set<string>* required,
  185. std::set<string>* forwards,
  186. bool* have_message) const;
  187. void FindRequiresForField(const GeneratorOptions& options,
  188. const FieldDescriptor* field,
  189. std::set<string>* required,
  190. std::set<string>* forwards) const;
  191. void FindRequiresForExtension(const GeneratorOptions& options,
  192. const FieldDescriptor* field,
  193. std::set<string>* required,
  194. std::set<string>* forwards) const;
  195. void GenerateFile(const GeneratorOptions& options,
  196. io::Printer* printer,
  197. const FileDescriptor* file) const;
  198. // Generate definitions for all message classes and enums in all files,
  199. // processing the files in dependence order.
  200. void GenerateFilesInDepOrder(
  201. const GeneratorOptions& options, io::Printer* printer,
  202. const std::vector<const FileDescriptor*>& file) const;
  203. // Helper for above.
  204. void GenerateFileAndDeps(const GeneratorOptions& options,
  205. io::Printer* printer,
  206. const FileDescriptor* root,
  207. std::set<const FileDescriptor*>* all_files,
  208. std::set<const FileDescriptor*>* generated) const;
  209. // Generate definitions for all message classes and enums.
  210. void GenerateClassesAndEnums(const GeneratorOptions& options,
  211. io::Printer* printer,
  212. const FileDescriptor* file) const;
  213. void GenerateFieldValueExpression(io::Printer* printer,
  214. const char* obj_reference,
  215. const FieldDescriptor* field,
  216. bool use_default) const;
  217. // Generate definition for one class.
  218. void GenerateClass(const GeneratorOptions& options,
  219. io::Printer* printer,
  220. const Descriptor* desc) const;
  221. void GenerateClassConstructor(const GeneratorOptions& options,
  222. io::Printer* printer,
  223. const Descriptor* desc) const;
  224. void GenerateClassFieldInfo(const GeneratorOptions& options,
  225. io::Printer* printer,
  226. const Descriptor* desc) const;
  227. void GenerateClassXid(const GeneratorOptions& options,
  228. io::Printer* printer,
  229. const Descriptor* desc) const;
  230. void GenerateOneofCaseDefinition(const GeneratorOptions& options,
  231. io::Printer* printer,
  232. const OneofDescriptor* oneof) const;
  233. void GenerateClassToObject(const GeneratorOptions& options,
  234. io::Printer* printer,
  235. const Descriptor* desc) const;
  236. void GenerateClassFieldToObject(const GeneratorOptions& options,
  237. io::Printer* printer,
  238. const FieldDescriptor* field) const;
  239. void GenerateClassFromObject(const GeneratorOptions& options,
  240. io::Printer* printer,
  241. const Descriptor* desc) const;
  242. void GenerateClassFieldFromObject(const GeneratorOptions& options,
  243. io::Printer* printer,
  244. const FieldDescriptor* field) const;
  245. void GenerateClassClone(const GeneratorOptions& options,
  246. io::Printer* printer,
  247. const Descriptor* desc) const;
  248. void GenerateClassRegistration(const GeneratorOptions& options,
  249. io::Printer* printer,
  250. const Descriptor* desc) const;
  251. void GenerateClassFields(const GeneratorOptions& options,
  252. io::Printer* printer,
  253. const Descriptor* desc) const;
  254. void GenerateClassField(const GeneratorOptions& options,
  255. io::Printer* printer,
  256. const FieldDescriptor* desc) const;
  257. void GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
  258. io::Printer* printer,
  259. const Descriptor* desc) const;
  260. void GenerateClassDeserialize(const GeneratorOptions& options,
  261. io::Printer* printer,
  262. const Descriptor* desc) const;
  263. void GenerateClassDeserializeBinary(const GeneratorOptions& options,
  264. io::Printer* printer,
  265. const Descriptor* desc) const;
  266. void GenerateClassDeserializeBinaryField(const GeneratorOptions& options,
  267. io::Printer* printer,
  268. const FieldDescriptor* field) const;
  269. void GenerateClassSerializeBinary(const GeneratorOptions& options,
  270. io::Printer* printer,
  271. const Descriptor* desc) const;
  272. void GenerateClassSerializeBinaryField(const GeneratorOptions& options,
  273. io::Printer* printer,
  274. const FieldDescriptor* field) const;
  275. // Generate definition for one enum.
  276. void GenerateEnum(const GeneratorOptions& options,
  277. io::Printer* printer,
  278. const EnumDescriptor* enumdesc) const;
  279. // Generate an extension definition.
  280. void GenerateExtension(const GeneratorOptions& options,
  281. io::Printer* printer,
  282. const FieldDescriptor* field) const;
  283. // Generate addFoo() method for repeated primitive fields.
  284. void GenerateRepeatedPrimitiveHelperMethods(const GeneratorOptions& options,
  285. io::Printer* printer,
  286. const FieldDescriptor* field,
  287. bool untyped) const;
  288. // Generate addFoo() method for repeated message fields.
  289. void GenerateRepeatedMessageHelperMethods(const GeneratorOptions& options,
  290. io::Printer* printer,
  291. const FieldDescriptor* field) const;
  292. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
  293. };
  294. } // namespace js
  295. } // namespace compiler
  296. } // namespace protobuf
  297. } // namespace google
  298. #endif // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__