Line data Source code
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 : #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 0 : const FileDescriptor* descriptor, bool immutable) {
126 0 : 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 compatibility 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 : const char* PrimitiveTypeName(JavaType type);
153 :
154 : // Get the fully-qualified class name for a boxed primitive type, e.g.
155 : // "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message
156 : // types.
157 : const char* BoxedPrimitiveTypeName(JavaType type);
158 :
159 : // Get the name of the java enum constant representing this type. E.g.,
160 : // "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full
161 : // name is "com.google.protobuf.WireFormat.FieldType.INT32".
162 : const char* FieldTypeName(const FieldDescriptor::Type field_type);
163 :
164 : class ClassNameResolver;
165 : string DefaultValue(const FieldDescriptor* field, bool immutable,
166 : ClassNameResolver* name_resolver);
167 : inline string ImmutableDefaultValue(const FieldDescriptor* field,
168 : ClassNameResolver* name_resolver) {
169 0 : return DefaultValue(field, true, name_resolver);
170 : }
171 : bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
172 :
173 : // Does this message class have generated parsing, serialization, and other
174 : // standard methods for which reflection-based fallback implementations exist?
175 0 : inline bool HasGeneratedMethods(const Descriptor* descriptor) {
176 0 : return descriptor->file()->options().optimize_for() !=
177 : FileOptions::CODE_SIZE;
178 : }
179 :
180 : // Does this message have specialized equals() and hashCode() methods?
181 0 : inline bool HasEqualsAndHashCode(const Descriptor* descriptor) {
182 0 : return descriptor->file()->options().java_generate_equals_and_hash();
183 : }
184 :
185 : // Does this message class have descriptor and reflection methods?
186 0 : inline bool HasDescriptorMethods(const Descriptor* descriptor) {
187 0 : return descriptor->file()->options().optimize_for() !=
188 : FileOptions::LITE_RUNTIME;
189 : }
190 0 : inline bool HasDescriptorMethods(const EnumDescriptor* descriptor) {
191 0 : return descriptor->file()->options().optimize_for() !=
192 : FileOptions::LITE_RUNTIME;
193 : }
194 0 : inline bool HasDescriptorMethods(const FileDescriptor* descriptor) {
195 0 : return descriptor->options().optimize_for() !=
196 : FileOptions::LITE_RUNTIME;
197 : }
198 :
199 : // Should we generate generic services for this file?
200 0 : inline bool HasGenericServices(const FileDescriptor *file) {
201 0 : return file->service_count() > 0 &&
202 0 : file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
203 0 : file->options().java_generic_services();
204 : }
205 :
206 0 : inline bool IsLazy(const FieldDescriptor* descriptor) {
207 : // Currently, the proto-lite version suports lazy field.
208 : // TODO(niwasaki): Support lazy fields also for other proto runtimes.
209 0 : if (descriptor->file()->options().optimize_for() !=
210 : FileOptions::LITE_RUNTIME) {
211 : return false;
212 : }
213 0 : return descriptor->options().lazy();
214 : }
215 :
216 : // Methods for shared bitfields.
217 :
218 : // Gets the name of the shared bitfield for the given index.
219 : string GetBitFieldName(int index);
220 :
221 : // Gets the name of the shared bitfield for the given bit index.
222 : // Effectively, GetBitFieldName(bitIndex / 32)
223 : string GetBitFieldNameForBit(int bitIndex);
224 :
225 : // Generates the java code for the expression that returns the boolean value
226 : // of the bit of the shared bitfields for the given bit index.
227 : // Example: "((bitField1_ & 0x04) == 0x04)"
228 : string GenerateGetBit(int bitIndex);
229 :
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 :
235 : // Generates the java code for the expression that clears the bit of the shared
236 : // bitfields for the given bit index.
237 : // Example: "bitField1_ = (bitField1_ & ~0x04)"
238 : string GenerateClearBit(int bitIndex);
239 :
240 : // Does the same as GenerateGetBit but operates on the bit field on a local
241 : // variable. This is used by the builder to copy the value in the builder to
242 : // the message.
243 : // Example: "((from_bitField1_ & 0x04) == 0x04)"
244 : string GenerateGetBitFromLocal(int bitIndex);
245 :
246 : // Does the same as GenerateSetBit but operates on the bit field on a local
247 : // variable. This is used by the builder to copy the value in the builder to
248 : // the message.
249 : // Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
250 : string GenerateSetBitToLocal(int bitIndex);
251 :
252 : // Does the same as GenerateGetBit but operates on the bit field on a local
253 : // variable. This is used by the parsing constructor to record if a repeated
254 : // field is mutable.
255 : // Example: "((mutable_bitField1_ & 0x04) == 0x04)"
256 : string GenerateGetBitMutableLocal(int bitIndex);
257 :
258 : // Does the same as GenerateSetBit but operates on the bit field on a local
259 : // variable. This is used by the parsing constructor to record if a repeated
260 : // field is mutable.
261 : // Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
262 : string GenerateSetBitMutableLocal(int bitIndex);
263 :
264 : // Returns whether the JavaType is a reference type.
265 : bool IsReferenceType(JavaType type);
266 :
267 : // Returns the capitalized name for calling relative functions in
268 : // CodedInputStream
269 : const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable);
270 :
271 : // For encodings with fixed sizes, returns that size in bytes. Otherwise
272 : // returns -1.
273 : int FixedSize(FieldDescriptor::Type type);
274 :
275 : // Comparators used to sort fields in MessageGenerator
276 : struct FieldOrderingByNumber {
277 0 : inline bool operator()(const FieldDescriptor* a,
278 0 : const FieldDescriptor* b) const {
279 0 : return a->number() < b->number();
280 : }
281 : };
282 :
283 : struct ExtensionRangeOrdering {
284 : bool operator()(const Descriptor::ExtensionRange* a,
285 : const Descriptor::ExtensionRange* b) const {
286 : return a->start < b->start;
287 : }
288 : };
289 :
290 : // Sort the fields of the given Descriptor by number into a new[]'d array
291 : // and return it. The caller should delete the returned array.
292 : const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);
293 :
294 : // Does this message class have any packed fields?
295 0 : inline bool HasPackedFields(const Descriptor* descriptor) {
296 0 : for (int i = 0; i < descriptor->field_count(); i++) {
297 0 : if (descriptor->field(i)->is_packed()) {
298 : return true;
299 : }
300 : }
301 : return false;
302 : }
303 :
304 : // Check a message type and its sub-message types recursively to see if any of
305 : // them has a required field. Return true if a required field is found.
306 : bool HasRequiredFields(const Descriptor* descriptor);
307 :
308 : // Whether a .proto file supports field presence test for non-message types.
309 0 : inline bool SupportFieldPresence(const FileDescriptor* descriptor) {
310 0 : return descriptor->syntax() != FileDescriptor::SYNTAX_PROTO3;
311 : }
312 :
313 : // Whether generate classes expose public PARSER instances.
314 0 : inline bool ExposePublicParser(const FileDescriptor* descriptor) {
315 : // TODO(liujisi): Mark the PARSER private in 3.1.x releases.
316 0 : return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
317 : }
318 :
319 : // Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet
320 : // but in the message and can be queried using additional getters that return
321 : // ints.
322 0 : inline bool SupportUnknownEnumValue(const FileDescriptor* descriptor) {
323 0 : return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
324 : }
325 :
326 : // Check whether a mesasge has repeated fields.
327 : bool HasRepeatedFields(const Descriptor* descriptor);
328 :
329 0 : inline bool IsMapEntry(const Descriptor* descriptor) {
330 0 : return descriptor->options().map_entry();
331 : }
332 :
333 : inline bool IsMapField(const FieldDescriptor* descriptor) {
334 : return descriptor->is_map();
335 : }
336 :
337 0 : inline bool PreserveUnknownFields(const Descriptor* descriptor) {
338 0 : return descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
339 : }
340 :
341 0 : inline bool IsAnyMessage(const Descriptor* descriptor) {
342 0 : return descriptor->full_name() == "google.protobuf.Any";
343 : }
344 :
345 0 : inline bool CheckUtf8(const FieldDescriptor* descriptor) {
346 0 : return descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
347 0 : descriptor->file()->options().java_string_check_utf8();
348 : }
349 :
350 : } // namespace java
351 : } // namespace compiler
352 : } // namespace protobuf
353 :
354 : } // namespace google
355 : #endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
|