java_helpers.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
  34. #define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
  35. #include <string>
  36. #include <google/protobuf/compiler/java/java_context.h>
  37. #include <google/protobuf/descriptor.pb.h>
  38. #include <google/protobuf/io/printer.h>
  39. #include <google/protobuf/descriptor.h>
  40. namespace google {
  41. namespace protobuf {
  42. namespace compiler {
  43. namespace java {
  44. // Commonly-used separator comments. Thick is a line of '=', thin is a line
  45. // of '-'.
  46. extern const char kThickSeparator[];
  47. extern const char kThinSeparator[];
  48. // If annotation_file is non-empty, prints a javax.annotation.Generated
  49. // annotation to the given Printer. annotation_file will be referenced in the
  50. // annotation's comments field. delimiter should be the Printer's delimiter
  51. // character. annotation_file will be included verbatim into a Java literal
  52. // string, so it should not contain quotes or invalid Java escape sequences;
  53. // however, these are unlikely to appear in practice, as the value of
  54. // annotation_file should be generated from the filename of the source file
  55. // being annotated (which in turn must be a Java identifier plus ".java").
  56. void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$',
  57. const string& annotation_file = "");
  58. // Converts a name to camel-case. If cap_first_letter is true, capitalize the
  59. // first letter.
  60. string UnderscoresToCamelCase(const string& name, bool cap_first_letter);
  61. // Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
  62. // "fooBarBaz" or "FooBarBaz", respectively.
  63. string UnderscoresToCamelCase(const FieldDescriptor* field);
  64. string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
  65. // Similar, but for method names. (Typically, this merely has the effect
  66. // of lower-casing the first letter of the name.)
  67. string UnderscoresToCamelCase(const MethodDescriptor* method);
  68. // Similar to UnderscoresToCamelCase, but guarentees that the result is a
  69. // complete Java identifier by adding a _ if needed.
  70. string CamelCaseFieldName(const FieldDescriptor* field);
  71. // Get an identifier that uniquely identifies this type within the file.
  72. // This is used to declare static variables related to this type at the
  73. // outermost file scope.
  74. string UniqueFileScopeIdentifier(const Descriptor* descriptor);
  75. // Strips ".proto" or ".protodevel" from the end of a filename.
  76. string StripProto(const string& filename);
  77. // Gets the unqualified class name for the file. For each .proto file, there
  78. // will be one Java class containing all the immutable messages and another
  79. // Java class containing all the mutable messages.
  80. // TODO(xiaofeng): remove the default value after updating client code.
  81. string FileClassName(const FileDescriptor* file, bool immutable = true);
  82. // Returns the file's Java package name.
  83. string FileJavaPackage(const FileDescriptor* file, bool immutable = true);
  84. // Returns output directory for the given package name.
  85. string JavaPackageToDir(string package_name);
  86. // Converts the given fully-qualified name in the proto namespace to its
  87. // fully-qualified name in the Java namespace, given that it is in the given
  88. // file.
  89. // TODO(xiaofeng): this method is deprecated and should be removed in the
  90. // future.
  91. string ToJavaName(const string& full_name,
  92. const FileDescriptor* file);
  93. // TODO(xiaofeng): the following methods are kept for they are exposed
  94. // publicly in //google/protobuf/compiler/java/names.h. They return
  95. // immutable names only and should be removed after mutable API is
  96. // integrated into google3.
  97. string ClassName(const Descriptor* descriptor);
  98. string ClassName(const EnumDescriptor* descriptor);
  99. string ClassName(const ServiceDescriptor* descriptor);
  100. string ClassName(const FileDescriptor* descriptor);
  101. // Comma-separate list of option-specified interfaces implemented by the
  102. // Message, to follow the "implements" declaration of the Message definition.
  103. string ExtraMessageInterfaces(const Descriptor* descriptor);
  104. // Comma-separate list of option-specified interfaces implemented by the
  105. // MutableMessage, to follow the "implements" declaration of the MutableMessage
  106. // definition.
  107. string ExtraMutableMessageInterfaces(const Descriptor* descriptor);
  108. // Comma-separate list of option-specified interfaces implemented by the
  109. // Builder, to follow the "implements" declaration of the Builder definition.
  110. string ExtraBuilderInterfaces(const Descriptor* descriptor);
  111. // Comma-separate list of option-specified interfaces extended by the
  112. // MessageOrBuilder, to follow the "extends" declaration of the
  113. // MessageOrBuilder definition.
  114. string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor);
  115. // Get the unqualified Java class name for mutable messages. i.e. without
  116. // package or outer classnames.
  117. inline string ShortMutableJavaClassName(const Descriptor* descriptor) {
  118. return descriptor->name();
  119. }
  120. // Whether the given descriptor is for one of the core descriptor protos. We
  121. // cannot currently use the new runtime with core protos since there is a
  122. // bootstrapping problem with obtaining their descriptors.
  123. inline bool IsDescriptorProto(const Descriptor* descriptor) {
  124. return descriptor->file()->name() == "google/protobuf/descriptor.proto";
  125. }
  126. // Whether we should generate multiple java files for messages.
  127. inline bool MultipleJavaFiles(
  128. const FileDescriptor* descriptor, bool immutable) {
  129. return descriptor->options().java_multiple_files();
  130. }
  131. // Returns true if `descriptor` will be written to its own .java file.
  132. // `immutable` should be set to true if we're generating for the immutable API.
  133. template <typename Descriptor>
  134. bool IsOwnFile(const Descriptor* descriptor, bool immutable) {
  135. return descriptor->containing_type() == NULL &&
  136. MultipleJavaFiles(descriptor->file(), immutable);
  137. }
  138. template <>
  139. inline bool IsOwnFile(const ServiceDescriptor* descriptor, bool immutable) {
  140. return MultipleJavaFiles(descriptor->file(), immutable);
  141. }
  142. // If `descriptor` describes an object with its own .java file,
  143. // returns the name (relative to that .java file) of the file that stores
  144. // annotation data for that descriptor. `suffix` is usually empty, but may
  145. // (e.g.) be "OrBuilder" for some generated interfaces.
  146. template <typename Descriptor>
  147. string AnnotationFileName(const Descriptor* descriptor, const string& suffix) {
  148. return descriptor->name() + suffix + ".java.pb.meta";
  149. }
  150. template <typename Descriptor>
  151. void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer,
  152. Descriptor* descriptor, bool immutable,
  153. const string& suffix = "") {
  154. if (context->options().annotate_code && IsOwnFile(descriptor, immutable)) {
  155. PrintGeneratedAnnotation(printer, '$',
  156. AnnotationFileName(descriptor, suffix));
  157. }
  158. }
  159. // Get the unqualified name that should be used for a field's field
  160. // number constant.
  161. string FieldConstantName(const FieldDescriptor *field);
  162. // Returns the type of the FieldDescriptor.
  163. // This does nothing interesting for the open source release, but is used for
  164. // hacks that improve compatibility with version 1 protocol buffers at Google.
  165. FieldDescriptor::Type GetType(const FieldDescriptor* field);
  166. enum JavaType {
  167. JAVATYPE_INT,
  168. JAVATYPE_LONG,
  169. JAVATYPE_FLOAT,
  170. JAVATYPE_DOUBLE,
  171. JAVATYPE_BOOLEAN,
  172. JAVATYPE_STRING,
  173. JAVATYPE_BYTES,
  174. JAVATYPE_ENUM,
  175. JAVATYPE_MESSAGE
  176. };
  177. JavaType GetJavaType(const FieldDescriptor* field);
  178. const char* PrimitiveTypeName(JavaType type);
  179. // Get the fully-qualified class name for a boxed primitive type, e.g.
  180. // "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message
  181. // types.
  182. const char* BoxedPrimitiveTypeName(JavaType type);
  183. // Get the name of the java enum constant representing this type. E.g.,
  184. // "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full
  185. // name is "com.google.protobuf.WireFormat.FieldType.INT32".
  186. const char* FieldTypeName(const FieldDescriptor::Type field_type);
  187. class ClassNameResolver;
  188. string DefaultValue(const FieldDescriptor* field, bool immutable,
  189. ClassNameResolver* name_resolver);
  190. inline string ImmutableDefaultValue(const FieldDescriptor* field,
  191. ClassNameResolver* name_resolver) {
  192. return DefaultValue(field, true, name_resolver);
  193. }
  194. bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
  195. bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field);
  196. // Does this message class have descriptor and reflection methods?
  197. inline bool HasDescriptorMethods(const Descriptor* descriptor,
  198. bool enforce_lite) {
  199. return !enforce_lite &&
  200. descriptor->file()->options().optimize_for() !=
  201. FileOptions::LITE_RUNTIME;
  202. }
  203. inline bool HasDescriptorMethods(const EnumDescriptor* descriptor,
  204. bool enforce_lite) {
  205. return !enforce_lite &&
  206. descriptor->file()->options().optimize_for() !=
  207. FileOptions::LITE_RUNTIME;
  208. }
  209. inline bool HasDescriptorMethods(const FileDescriptor* descriptor,
  210. bool enforce_lite) {
  211. return !enforce_lite &&
  212. descriptor->options().optimize_for() != FileOptions::LITE_RUNTIME;
  213. }
  214. // Should we generate generic services for this file?
  215. inline bool HasGenericServices(const FileDescriptor *file, bool enforce_lite) {
  216. return file->service_count() > 0 &&
  217. HasDescriptorMethods(file, enforce_lite) &&
  218. file->options().java_generic_services();
  219. }
  220. // Methods for shared bitfields.
  221. // Gets the name of the shared bitfield for the given index.
  222. string GetBitFieldName(int index);
  223. // Gets the name of the shared bitfield for the given bit index.
  224. // Effectively, GetBitFieldName(bitIndex / 32)
  225. string GetBitFieldNameForBit(int bitIndex);
  226. // Generates the java code for the expression that returns the boolean value
  227. // of the bit of the shared bitfields for the given bit index.
  228. // Example: "((bitField1_ & 0x04) == 0x04)"
  229. string GenerateGetBit(int bitIndex);
  230. // Generates the java code for the expression that sets the bit of the shared
  231. // bitfields for the given bit index.
  232. // Example: "bitField1_ = (bitField1_ | 0x04)"
  233. string GenerateSetBit(int bitIndex);
  234. // Generates the java code for the expression that clears the bit of the shared
  235. // bitfields for the given bit index.
  236. // Example: "bitField1_ = (bitField1_ & ~0x04)"
  237. string GenerateClearBit(int bitIndex);
  238. // Does the same as GenerateGetBit but operates on the bit field on a local
  239. // variable. This is used by the builder to copy the value in the builder to
  240. // the message.
  241. // Example: "((from_bitField1_ & 0x04) == 0x04)"
  242. string GenerateGetBitFromLocal(int bitIndex);
  243. // Does the same as GenerateSetBit but operates on the bit field on a local
  244. // variable. This is used by the builder to copy the value in the builder to
  245. // the message.
  246. // Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
  247. string GenerateSetBitToLocal(int bitIndex);
  248. // Does the same as GenerateGetBit but operates on the bit field on a local
  249. // variable. This is used by the parsing constructor to record if a repeated
  250. // field is mutable.
  251. // Example: "((mutable_bitField1_ & 0x04) == 0x04)"
  252. string GenerateGetBitMutableLocal(int bitIndex);
  253. // Does the same as GenerateSetBit but operates on the bit field on a local
  254. // variable. This is used by the parsing constructor to record if a repeated
  255. // field is mutable.
  256. // Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
  257. string GenerateSetBitMutableLocal(int bitIndex);
  258. // Returns whether the JavaType is a reference type.
  259. bool IsReferenceType(JavaType type);
  260. // Returns the capitalized name for calling relative functions in
  261. // CodedInputStream
  262. const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable);
  263. // For encodings with fixed sizes, returns that size in bytes. Otherwise
  264. // returns -1.
  265. int FixedSize(FieldDescriptor::Type type);
  266. // Comparators used to sort fields in MessageGenerator
  267. struct FieldOrderingByNumber {
  268. inline bool operator()(const FieldDescriptor* a,
  269. const FieldDescriptor* b) const {
  270. return a->number() < b->number();
  271. }
  272. };
  273. struct ExtensionRangeOrdering {
  274. bool operator()(const Descriptor::ExtensionRange* a,
  275. const Descriptor::ExtensionRange* b) const {
  276. return a->start < b->start;
  277. }
  278. };
  279. // Sort the fields of the given Descriptor by number into a new[]'d array
  280. // and return it. The caller should delete the returned array.
  281. const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);
  282. // Does this message class have any packed fields?
  283. inline bool HasPackedFields(const Descriptor* descriptor) {
  284. for (int i = 0; i < descriptor->field_count(); i++) {
  285. if (descriptor->field(i)->is_packed()) {
  286. return true;
  287. }
  288. }
  289. return false;
  290. }
  291. // Check a message type and its sub-message types recursively to see if any of
  292. // them has a required field. Return true if a required field is found.
  293. bool HasRequiredFields(const Descriptor* descriptor);
  294. // Whether a .proto file supports field presence test for non-message types.
  295. inline bool SupportFieldPresence(const FileDescriptor* descriptor) {
  296. return descriptor->syntax() != FileDescriptor::SYNTAX_PROTO3;
  297. }
  298. // Whether generate classes expose public PARSER instances.
  299. inline bool ExposePublicParser(const FileDescriptor* descriptor) {
  300. // TODO(liujisi): Mark the PARSER private in 3.1.x releases.
  301. return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
  302. }
  303. // Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet
  304. // but in the message and can be queried using additional getters that return
  305. // ints.
  306. inline bool SupportUnknownEnumValue(const FileDescriptor* descriptor) {
  307. return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
  308. }
  309. // Check whether a mesasge has repeated fields.
  310. bool HasRepeatedFields(const Descriptor* descriptor);
  311. inline bool IsMapEntry(const Descriptor* descriptor) {
  312. return descriptor->options().map_entry();
  313. }
  314. inline bool IsMapField(const FieldDescriptor* descriptor) {
  315. return descriptor->is_map();
  316. }
  317. inline bool IsAnyMessage(const Descriptor* descriptor) {
  318. return descriptor->full_name() == "google.protobuf.Any";
  319. }
  320. inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) {
  321. return descriptor->name() == "google/protobuf/wrappers.proto";
  322. }
  323. inline bool CheckUtf8(const FieldDescriptor* descriptor) {
  324. return descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
  325. descriptor->file()->options().java_string_check_utf8();
  326. }
  327. inline string GeneratedCodeVersionSuffix() {
  328. return "V3";
  329. }
  330. inline bool EnableExperimentalRuntime(Context* context) {
  331. return false;
  332. }
  333. void WriteUInt32ToUtf16CharSequence(uint32 number, std::vector<uint16>* output);
  334. inline void WriteIntToUtf16CharSequence(int value,
  335. std::vector<uint16>* output) {
  336. WriteUInt32ToUtf16CharSequence(static_cast<uint32>(value), output);
  337. }
  338. // Escape a UTF-16 character so it can be embedded in a Java string literal.
  339. void EscapeUtf16ToString(uint16 code, string* output);
  340. // Only the lowest two bytes of the return value are used. The lowest byte
  341. // is the integer value of a j/c/g/protobuf/FieldType enum. For the other
  342. // byte:
  343. // bit 0: whether the field is required.
  344. // bit 1: whether the field requires UTF-8 validation.
  345. // bit 2: whether the field needs isInitialized check.
  346. // bit 3: whether the field is a map field with proto2 enum value.
  347. // bits 4-7: unused
  348. int GetExperimentalJavaFieldType(const FieldDescriptor* field);
  349. // To get the total number of entries need to be built for experimental runtime
  350. // and the first field number that are not in the table part
  351. std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber(
  352. const FieldDescriptor** fields, int count);
  353. } // namespace java
  354. } // namespace compiler
  355. } // namespace protobuf
  356. } // namespace google
  357. #endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__