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 (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 35 #ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ 36 #define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ 37 38 #include <string> 39 #include <google/protobuf/descriptor.pb.h> 40 #include <google/protobuf/descriptor.h> 41 42 namespace google { 43 namespace protobuf { 44 namespace compiler { 45 namespace java { 46 47 // Commonly-used separator comments. Thick is a line of '=', thin is a line 48 // of '-'. 49 extern const char kThickSeparator[]; 50 extern const char kThinSeparator[]; 51 52 // Converts a name to camel-case. If cap_first_letter is true, capitalize the 53 // first letter. 54 string UnderscoresToCamelCase(const string& name, bool cap_first_letter); 55 // Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes 56 // "fooBarBaz" or "FooBarBaz", respectively. 57 string UnderscoresToCamelCase(const FieldDescriptor* field); 58 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); 59 60 // Similar, but for method names. (Typically, this merely has the effect 61 // of lower-casing the first letter of the name.) 62 string UnderscoresToCamelCase(const MethodDescriptor* method); 63 64 // Get an identifier that uniquely identifies this type within the file. 65 // This is used to declare static variables related to this type at the 66 // outermost file scope. 67 string UniqueFileScopeIdentifier(const Descriptor* descriptor); 68 69 // Strips ".proto" or ".protodevel" from the end of a filename. 70 string StripProto(const string& filename); 71 72 // Gets the unqualified class name for the file. For each .proto file, there 73 // will be one Java class containing all the immutable messages and another 74 // Java class containing all the mutable messages. 75 // TODO(xiaofeng): remove the default value after updating client code. 76 string FileClassName(const FileDescriptor* file, bool immutable = true); 77 78 // Returns the file's Java package name. 79 string FileJavaPackage(const FileDescriptor* file, bool immutable = true); 80 81 // Returns output directory for the given package name. 82 string JavaPackageToDir(string package_name); 83 84 // Converts the given fully-qualified name in the proto namespace to its 85 // fully-qualified name in the Java namespace, given that it is in the given 86 // file. 87 // TODO(xiaofeng): this method is deprecated and should be removed in the 88 // future. 89 string ToJavaName(const string& full_name, 90 const FileDescriptor* file); 91 92 // TODO(xiaofeng): the following methods are kept for they are exposed 93 // publicly in //google/protobuf/compiler/java/names.h. They return 94 // immutable names only and should be removed after mutable API is 95 // integrated into google3. 96 string ClassName(const Descriptor* descriptor); 97 string ClassName(const EnumDescriptor* descriptor); 98 string ClassName(const ServiceDescriptor* descriptor); 99 string ClassName(const FileDescriptor* descriptor); 100 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 116 // Get the unqualified Java class name for mutable messages. i.e. without 117 // package or outer classnames. 118 inline string ShortMutableJavaClassName(const Descriptor* descriptor) { 119 return descriptor->name(); 120 } 121 122 123 // Whether we should generate multiple java files for messages. 124 inline bool MultipleJavaFiles( 125 const FileDescriptor* descriptor, bool immutable) { 126 return descriptor->options().java_multiple_files(); 127 } 128 129 // Get the unqualified name that should be used for a field's field 130 // number constant. 131 string FieldConstantName(const FieldDescriptor *field); 132 133 // Returns the type of the FieldDescriptor. 134 // This does nothing interesting for the open source release, but is used for 135 // hacks that improve compatability with version 1 protocol buffers at Google. 136 FieldDescriptor::Type GetType(const FieldDescriptor* field); 137 138 enum JavaType { 139 JAVATYPE_INT, 140 JAVATYPE_LONG, 141 JAVATYPE_FLOAT, 142 JAVATYPE_DOUBLE, 143 JAVATYPE_BOOLEAN, 144 JAVATYPE_STRING, 145 JAVATYPE_BYTES, 146 JAVATYPE_ENUM, 147 JAVATYPE_MESSAGE 148 }; 149 150 JavaType GetJavaType(const FieldDescriptor* field); 151 152 // Get the fully-qualified class name for a boxed primitive type, e.g. 153 // "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message 154 // types. 155 const char* BoxedPrimitiveTypeName(JavaType type); 156 157 // Get the name of the java enum constant representing this type. E.g., 158 // "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full 159 // name is "com.google.protobuf.WireFormat.FieldType.INT32". 160 const char* FieldTypeName(const FieldDescriptor::Type field_type); 161 162 class ClassNameResolver; 163 string DefaultValue(const FieldDescriptor* field, bool immutable, 164 ClassNameResolver* name_resolver); 165 inline string ImmutableDefaultValue(const FieldDescriptor* field, 166 ClassNameResolver* name_resolver) { 167 return DefaultValue(field, true, name_resolver); 168 } 169 bool IsDefaultValueJavaDefault(const FieldDescriptor* field); 170 171 // Does this message class use UnknownFieldSet? 172 // Otherwise, unknown fields will be stored in a ByteString object 173 inline bool UseUnknownFieldSet(const Descriptor* descriptor) { 174 return descriptor->file()->options().optimize_for() != 175 FileOptions::LITE_RUNTIME; 176 } 177 178 // Does this message class have generated parsing, serialization, and other 179 // standard methods for which reflection-based fallback implementations exist? 180 inline bool HasGeneratedMethods(const Descriptor* descriptor) { 181 return descriptor->file()->options().optimize_for() != 182 FileOptions::CODE_SIZE; 183 } 184 185 // Does this message have specialized equals() and hashCode() methods? 186 inline bool HasEqualsAndHashCode(const Descriptor* descriptor) { 187 return descriptor->file()->options().java_generate_equals_and_hash(); 188 } 189 190 // Does this message class have descriptor and reflection methods? 191 inline bool HasDescriptorMethods(const Descriptor* descriptor) { 192 return descriptor->file()->options().optimize_for() != 193 FileOptions::LITE_RUNTIME; 194 } 195 inline bool HasDescriptorMethods(const EnumDescriptor* descriptor) { 196 return descriptor->file()->options().optimize_for() != 197 FileOptions::LITE_RUNTIME; 198 } 199 inline bool HasDescriptorMethods(const FileDescriptor* descriptor) { 200 return descriptor->options().optimize_for() != 201 FileOptions::LITE_RUNTIME; 202 } 203 204 inline bool HasNestedBuilders(const Descriptor* descriptor) { 205 // The proto-lite version doesn't support nested builders. 206 return descriptor->file()->options().optimize_for() != 207 FileOptions::LITE_RUNTIME; 208 } 209 210 // Should we generate generic services for this file? 211 inline bool HasGenericServices(const FileDescriptor *file) { 212 return file->service_count() > 0 && 213 file->options().optimize_for() != FileOptions::LITE_RUNTIME && 214 file->options().java_generic_services(); 215 } 216 217 inline bool IsLazy(const FieldDescriptor* descriptor) { 218 // Currently, the proto-lite version suports lazy field. 219 // TODO(niwasaki): Support lazy fields also for other proto runtimes. 220 if (descriptor->file()->options().optimize_for() != 221 FileOptions::LITE_RUNTIME) { 222 return false; 223 } 224 return descriptor->options().lazy(); 225 } 226 227 // Methods for shared bitfields. 228 229 // Gets the name of the shared bitfield for the given index. 230 string GetBitFieldName(int index); 231 232 // Gets the name of the shared bitfield for the given bit index. 233 // Effectively, GetBitFieldName(bitIndex / 32) 234 string GetBitFieldNameForBit(int bitIndex); 235 236 // Generates the java code for the expression that returns the boolean value 237 // of the bit of the shared bitfields for the given bit index. 238 // Example: "((bitField1_ & 0x04) == 0x04)" 239 string GenerateGetBit(int bitIndex); 240 241 // Generates the java code for the expression that sets the bit of the shared 242 // bitfields for the given bit index. 243 // Example: "bitField1_ = (bitField1_ | 0x04)" 244 string GenerateSetBit(int bitIndex); 245 246 // Generates the java code for the expression that clears the bit of the shared 247 // bitfields for the given bit index. 248 // Example: "bitField1_ = (bitField1_ & ~0x04)" 249 string GenerateClearBit(int bitIndex); 250 251 // Does the same as GenerateGetBit but operates on the bit field on a local 252 // variable. This is used by the builder to copy the value in the builder to 253 // the message. 254 // Example: "((from_bitField1_ & 0x04) == 0x04)" 255 string GenerateGetBitFromLocal(int bitIndex); 256 257 // Does the same as GenerateSetBit but operates on the bit field on a local 258 // variable. This is used by the builder to copy the value in the builder to 259 // the message. 260 // Example: "to_bitField1_ = (to_bitField1_ | 0x04)" 261 string GenerateSetBitToLocal(int bitIndex); 262 263 // Does the same as GenerateGetBit but operates on the bit field on a local 264 // variable. This is used by the parsing constructor to record if a repeated 265 // field is mutable. 266 // Example: "((mutable_bitField1_ & 0x04) == 0x04)" 267 string GenerateGetBitMutableLocal(int bitIndex); 268 269 // Does the same as GenerateSetBit but operates on the bit field on a local 270 // variable. This is used by the parsing constructor to record if a repeated 271 // field is mutable. 272 // Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)" 273 string GenerateSetBitMutableLocal(int bitIndex); 274 275 // Returns whether the JavaType is a reference type. 276 bool IsReferenceType(JavaType type); 277 278 // Returns the capitalized name for calling relative functions in 279 // CodedInputStream 280 const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable); 281 282 // For encodings with fixed sizes, returns that size in bytes. Otherwise 283 // returns -1. 284 int FixedSize(FieldDescriptor::Type type); 285 286 // Comparators used to sort fields in MessageGenerator 287 struct FieldOrderingByNumber { 288 inline bool operator()(const FieldDescriptor* a, 289 const FieldDescriptor* b) const { 290 return a->number() < b->number(); 291 } 292 }; 293 294 struct ExtensionRangeOrdering { 295 bool operator()(const Descriptor::ExtensionRange* a, 296 const Descriptor::ExtensionRange* b) const { 297 return a->start < b->start; 298 } 299 }; 300 301 // Sort the fields of the given Descriptor by number into a new[]'d array 302 // and return it. The caller should delete the returned array. 303 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor); 304 305 // Check a message type and its sub-message types recursively to see if any of 306 // them has a required field. Return true if a required field is found. 307 bool HasRequiredFields(const Descriptor* descriptor); 308 309 // Whether a .proto file supports field presence test for non-message types. 310 inline bool SupportFieldPresence(const FileDescriptor* descriptor) { 311 return true; 312 } 313 314 // Check whether a mesasge has repeated fields. 315 bool HasRepeatedFields(const Descriptor* descriptor); 316 317 } // namespace java 318 } // namespace compiler 319 } // namespace protobuf 320 321 } // namespace google 322 #endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ 323