Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-04 09:09:19

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 
0012 #ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
0013 #define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
0014 
0015 #include <cstdint>
0016 #include <string>
0017 
0018 #include "absl/status/status.h"
0019 #include "absl/strings/string_view.h"
0020 #include "google/protobuf/compiler/java/names.h"
0021 #include "google/protobuf/compiler/java/options.h"
0022 #include "google/protobuf/descriptor.h"
0023 #include "google/protobuf/descriptor.pb.h"
0024 #include "google/protobuf/io/printer.h"
0025 
0026 // Must be last.
0027 #include "google/protobuf/port_def.inc"
0028 
0029 namespace google {
0030 namespace protobuf {
0031 namespace compiler {
0032 namespace java {
0033 
0034 // Commonly-used separator comments.  Thick is a line of '=', thin is a line
0035 // of '-'.
0036 extern const char kThickSeparator[];
0037 extern const char kThinSeparator[];
0038 
0039 bool IsForbiddenKotlin(absl::string_view field_name);
0040 
0041 // If annotation_file is non-empty, prints a javax.annotation.Generated
0042 // annotation to the given Printer. annotation_file will be referenced in the
0043 // annotation's comments field. delimiter should be the Printer's delimiter
0044 // character. annotation_file will be included verbatim into a Java literal
0045 // string, so it should not contain quotes or invalid Java escape sequences;
0046 // however, these are unlikely to appear in practice, as the value of
0047 // annotation_file should be generated from the filename of the source file
0048 // being annotated (which in turn must be a Java identifier plus ".java").
0049 void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$',
0050                               absl::string_view annotation_file = "",
0051                               Options options = {});
0052 
0053 // If a GeneratedMessageLite contains non-lite enums, then its verifier
0054 // must be instantiated inline, rather than retrieved from the enum class.
0055 void PrintEnumVerifierLogic(
0056     io::Printer* printer, const FieldDescriptor* descriptor,
0057     const absl::flat_hash_map<absl::string_view, std::string>& variables,
0058     absl::string_view var_name, absl::string_view terminating_string,
0059     bool enforce_lite);
0060 
0061 // Prints the Protobuf Java Version validator checking that the runtime and
0062 // gencode versions are compatible.
0063 void PrintGencodeVersionValidator(io::Printer* printer, bool oss_runtime,
0064                                   absl::string_view java_class_name);
0065 
0066 // Converts a name to camel-case. If cap_first_letter is true, capitalize the
0067 // first letter.
0068 std::string ToCamelCase(absl::string_view input, bool lower_first);
0069 
0070 // Similar to UnderscoresToCamelCase, but guarantees that the result is a
0071 // complete Java identifier by adding a _ if needed.
0072 std::string CamelCaseFieldName(const FieldDescriptor* field);
0073 
0074 // Get an identifier that uniquely identifies this type within the file.
0075 // This is used to declare static variables related to this type at the
0076 // outermost file scope.
0077 std::string UniqueFileScopeIdentifier(const Descriptor* descriptor);
0078 
0079 // Gets the unqualified class name for the file.  For each .proto file, there
0080 // will be one Java class containing all the immutable messages and another
0081 // Java class containing all the mutable messages.
0082 std::string FileClassName(const FileDescriptor* file, bool immutable);
0083 
0084 // Returns the file's Java package name.
0085 std::string FileJavaPackage(const FileDescriptor* file, bool immutable,
0086                             Options options = {});
0087 
0088 // Returns output directory for the given package name.
0089 std::string JavaPackageToDir(std::string package_name);
0090 
0091 // Returns the name with Kotlin keywords enclosed in backticks
0092 std::string EscapeKotlinKeywords(std::string name);
0093 
0094 // Comma-separate list of option-specified interfaces implemented by the
0095 // Message, to follow the "implements" declaration of the Message definition.
0096 std::string ExtraMessageInterfaces(const Descriptor* descriptor);
0097 // Comma-separate list of option-specified interfaces implemented by the
0098 // MutableMessage, to follow the "implements" declaration of the MutableMessage
0099 // definition.
0100 std::string ExtraMutableMessageInterfaces(const Descriptor* descriptor);
0101 // Comma-separate list of option-specified interfaces implemented by the
0102 // Builder, to follow the "implements" declaration of the Builder definition.
0103 std::string ExtraBuilderInterfaces(const Descriptor* descriptor);
0104 // Comma-separate list of option-specified interfaces extended by the
0105 // MessageOrBuilder, to follow the "extends" declaration of the
0106 // MessageOrBuilder definition.
0107 std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor);
0108 
0109 // Get the unqualified Java class name for mutable messages. i.e. without
0110 // package or outer classnames.
0111 inline std::string ShortMutableJavaClassName(const Descriptor* descriptor) {
0112   return std::string(descriptor->name());
0113 }
0114 
0115 // Whether the given descriptor is for one of the core descriptor protos. We
0116 // cannot currently use the new runtime with core protos since there is a
0117 // bootstrapping problem with obtaining their descriptors.
0118 inline bool IsDescriptorProto(const Descriptor* descriptor) {
0119   return descriptor->file()->name() == "net/proto2/proto/descriptor.proto" ||
0120          descriptor->file()->name() == "google/protobuf/descriptor.proto";
0121 }
0122 
0123 // Returns the stored type string used by the experimental runtime for oneof
0124 // fields.
0125 std::string GetOneofStoredType(const FieldDescriptor* field);
0126 
0127 // We use either the proto1 enums if the enum is generated, otherwise fall back
0128 // to use integers.
0129 enum class Proto1EnumRepresentation {
0130   kEnum,
0131   kInteger,
0132 };
0133 
0134 // Returns which representation we should use.
0135 inline Proto1EnumRepresentation GetProto1EnumRepresentation(
0136     const EnumDescriptor* descriptor) {
0137   if (descriptor->containing_type() != nullptr) {
0138     return Proto1EnumRepresentation::kEnum;
0139   }
0140   return Proto1EnumRepresentation::kInteger;
0141 }
0142 
0143 absl::Status ValidateNestInFileClassFeature(const Descriptor& descriptor);
0144 absl::Status ValidateNestInFileClassFeature(const EnumDescriptor& descriptor);
0145 
0146 // Returns true if the generated class for the type is nested in the generated
0147 // proto file Java class.
0148 // `immutable` should be set to true if we're generating for the immutable API.
0149 bool NestedInFileClass(const Descriptor& descriptor, bool immutable);
0150 bool NestedInFileClass(const EnumDescriptor& descriptor, bool immutable);
0151 bool NestedInFileClass(const ServiceDescriptor& descriptor, bool immutable);
0152 
0153 
0154 // Returns true if `descriptor` will be written to its own .java file.
0155 // `immutable` should be set to true if we're generating for the immutable API.
0156 // For nested messages, this always returns false, since their generated Java
0157 // class is always nested in their parent message's Java class i.e. they never
0158 // have their own standalone Java file.
0159 template <typename Descriptor>
0160 bool IsOwnFile(const Descriptor* descriptor, bool immutable) {
0161   return descriptor->containing_type() == nullptr &&
0162          !NestedInFileClass(*descriptor, immutable);
0163 }
0164 
0165 template <>
0166 inline bool IsOwnFile(const ServiceDescriptor* descriptor, bool immutable) {
0167   return !NestedInFileClass(*descriptor, immutable);
0168 }
0169 
0170 // If `descriptor` describes an object with its own .java file,
0171 // returns the name (relative to that .java file) of the file that stores
0172 // annotation data for that descriptor. `suffix` is usually empty, but may
0173 // (e.g.) be "OrBuilder" for some generated interfaces.
0174 template <typename Descriptor>
0175 std::string AnnotationFileName(const Descriptor* descriptor,
0176                                absl::string_view suffix) {
0177   return absl::StrCat(descriptor->name(), suffix, ".java.pb.meta");
0178 }
0179 
0180 // Get the unqualified name that should be used for a field's field
0181 // number constant.
0182 std::string FieldConstantName(const FieldDescriptor* field);
0183 
0184 // Returns the type of the FieldDescriptor.
0185 // This does nothing interesting for the open source release, but is used for
0186 // hacks that improve compatibility with version 1 protocol buffers at Google.
0187 FieldDescriptor::Type GetType(const FieldDescriptor* field);
0188 
0189 enum JavaType {
0190   JAVATYPE_INT,
0191   JAVATYPE_LONG,
0192   JAVATYPE_FLOAT,
0193   JAVATYPE_DOUBLE,
0194   JAVATYPE_BOOLEAN,
0195   JAVATYPE_STRING,
0196   JAVATYPE_BYTES,
0197   JAVATYPE_ENUM,
0198   JAVATYPE_MESSAGE
0199 };
0200 
0201 JavaType GetJavaType(const FieldDescriptor* field);
0202 
0203 absl::string_view PrimitiveTypeName(JavaType type);
0204 
0205 // Get the fully-qualified class name for a boxed primitive type, e.g.
0206 // "java.lang.Integer" for JAVATYPE_INT.  Returns NULL for enum and message
0207 // types.
0208 absl::string_view BoxedPrimitiveTypeName(JavaType type);
0209 
0210 // Kotlin source does not distinguish between primitives and non-primitives,
0211 // but does use Kotlin-specific qualified types for them.
0212 absl::string_view KotlinTypeName(JavaType type);
0213 
0214 // Get the name of the java enum constant representing this type. E.g.,
0215 // "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full
0216 // name is "com.google.protobuf.WireFormat.FieldType.INT32".
0217 absl::string_view FieldTypeName(FieldDescriptor::Type field_type);
0218 
0219 class ClassNameResolver;
0220 std::string DefaultValue(const FieldDescriptor* field, bool immutable,
0221                          ClassNameResolver* name_resolver,
0222                          Options options = {});
0223 inline std::string ImmutableDefaultValue(const FieldDescriptor* field,
0224                                          ClassNameResolver* name_resolver,
0225                                          Options options = {}) {
0226   return DefaultValue(field, true, name_resolver, options);
0227 }
0228 bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
0229 bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field);
0230 
0231 // Does this message class have descriptor and reflection methods?
0232 inline bool HasDescriptorMethods(const Descriptor* /* descriptor */,
0233                                  bool enforce_lite) {
0234   return !enforce_lite;
0235 }
0236 inline bool HasDescriptorMethods(const EnumDescriptor* /* descriptor */,
0237                                  bool enforce_lite) {
0238   return !enforce_lite;
0239 }
0240 inline bool HasDescriptorMethods(const FileDescriptor* /* descriptor */,
0241                                  bool enforce_lite) {
0242   return !enforce_lite;
0243 }
0244 
0245 // Should we generate generic services for this file?
0246 inline bool HasGenericServices(const FileDescriptor* file, bool enforce_lite) {
0247   return file->service_count() > 0 &&
0248          HasDescriptorMethods(file, enforce_lite) &&
0249          file->options().java_generic_services();
0250 }
0251 
0252 // Methods for shared bitfields.
0253 
0254 // Gets the name of the shared bitfield for the given index.
0255 std::string GetBitFieldName(int index);
0256 
0257 // Gets the name of the shared bitfield for the given bit index.
0258 // Effectively, GetBitFieldName(bitIndex / 32)
0259 std::string GetBitFieldNameForBit(int bitIndex);
0260 
0261 // Generates the java code for the expression that returns the boolean value
0262 // of the bit of the shared bitfields for the given bit index.
0263 // Example: "((bitField1_ & 0x04) == 0x04)"
0264 std::string GenerateGetBit(int bitIndex);
0265 
0266 // Generates the java code for the expression that sets the bit of the shared
0267 // bitfields for the given bit index.
0268 // Example: "bitField1_ = (bitField1_ | 0x04)"
0269 std::string GenerateSetBit(int bitIndex);
0270 
0271 // Generates the java code for the expression that clears the bit of the shared
0272 // bitfields for the given bit index.
0273 // Example: "bitField1_ = (bitField1_ & ~0x04)"
0274 std::string GenerateClearBit(int bitIndex);
0275 
0276 // Does the same as GenerateGetBit but operates on the bit field on a local
0277 // variable. This is used by the builder to copy the value in the builder to
0278 // the message.
0279 // Example: "((from_bitField1_ & 0x04) == 0x04)"
0280 std::string GenerateGetBitFromLocal(int bitIndex);
0281 
0282 // Does the same as GenerateSetBit but operates on the bit field on a local
0283 // variable. This is used by the builder to copy the value in the builder to
0284 // the message.
0285 // Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
0286 std::string GenerateSetBitToLocal(int bitIndex);
0287 
0288 // Does the same as GenerateGetBit but operates on the bit field on a local
0289 // variable. This is used by the parsing constructor to record if a repeated
0290 // field is mutable.
0291 // Example: "((mutable_bitField1_ & 0x04) == 0x04)"
0292 std::string GenerateGetBitMutableLocal(int bitIndex);
0293 
0294 // Does the same as GenerateSetBit but operates on the bit field on a local
0295 // variable. This is used by the parsing constructor to record if a repeated
0296 // field is mutable.
0297 // Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
0298 std::string GenerateSetBitMutableLocal(int bitIndex);
0299 
0300 // Returns whether the JavaType is a reference type.
0301 bool IsReferenceType(JavaType type);
0302 
0303 // Returns the capitalized name for calling relative functions in
0304 // CodedInputStream
0305 absl::string_view GetCapitalizedType(const FieldDescriptor* field,
0306                                      bool immutable, Options options);
0307 
0308 // For encodings with fixed sizes, returns that size in bytes.  Otherwise
0309 // returns -1.
0310 int FixedSize(FieldDescriptor::Type type);
0311 
0312 // Comparators used to sort fields in MessageGenerator
0313 struct FieldOrderingByNumber {
0314   inline bool operator()(const FieldDescriptor* a,
0315                          const FieldDescriptor* b) const {
0316     return a->number() < b->number();
0317   }
0318 };
0319 
0320 struct ExtensionRangeOrdering {
0321   bool operator()(const Descriptor::ExtensionRange* a,
0322                   const Descriptor::ExtensionRange* b) const {
0323     return a->start_number() < b->start_number();
0324   }
0325 };
0326 
0327 // Sort the fields of the given Descriptor by number into a new[]'d array
0328 // and return it. The caller should delete the returned array.
0329 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);
0330 
0331 // Does this message class have any packed fields?
0332 inline bool HasPackedFields(const Descriptor* descriptor) {
0333   for (int i = 0; i < descriptor->field_count(); i++) {
0334     if (descriptor->field(i)->is_packed()) {
0335       return true;
0336     }
0337   }
0338   return false;
0339 }
0340 
0341 // Check a message type and its sub-message types recursively to see if any of
0342 // them has a required field. Return true if a required field is found.
0343 bool HasRequiredFields(const Descriptor* descriptor);
0344 
0345 bool IsRealOneof(const FieldDescriptor* descriptor);
0346 
0347 inline bool HasHasbit(const FieldDescriptor* descriptor) {
0348   return descriptor->has_presence() && !descriptor->real_containing_oneof();
0349 }
0350 
0351 // Check whether a message has repeated fields.
0352 bool HasRepeatedFields(const Descriptor* descriptor);
0353 
0354 inline bool IsMapEntry(const Descriptor* descriptor) {
0355   return descriptor->options().map_entry();
0356 }
0357 
0358 inline bool IsMapField(const FieldDescriptor* descriptor) {
0359   return descriptor->is_map();
0360 }
0361 
0362 inline bool IsAnyMessage(const Descriptor* descriptor) {
0363   return descriptor->full_name() == "google.protobuf.Any";
0364 }
0365 
0366 inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) {
0367   return descriptor->name() == "google/protobuf/wrappers.proto";
0368 }
0369 
0370 void WriteUInt32ToUtf16CharSequence(uint32_t number,
0371                                     std::vector<uint16_t>* output);
0372 
0373 inline void WriteIntToUtf16CharSequence(int value,
0374                                         std::vector<uint16_t>* output) {
0375   WriteUInt32ToUtf16CharSequence(static_cast<uint32_t>(value), output);
0376 }
0377 
0378 // Escape a UTF-16 character so it can be embedded in a Java string literal.
0379 void EscapeUtf16ToString(uint16_t code, std::string* output);
0380 
0381 // To get the total number of entries need to be built for experimental runtime
0382 // and the first field number that are not in the table part
0383 std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber(
0384     const FieldDescriptor** fields, int count);
0385 
0386 const FieldDescriptor* MapKeyField(const FieldDescriptor* descriptor);
0387 
0388 const FieldDescriptor* MapValueField(const FieldDescriptor* descriptor);
0389 
0390 inline std::string JvmSynthetic(bool jvm_dsl) {
0391   return jvm_dsl ? "@kotlin.jvm.JvmSynthetic\n" : "";
0392 }
0393 
0394 struct JvmNameContext {
0395   const Options& options;
0396   io::Printer* printer;
0397   bool lite = true;
0398 };
0399 
0400 inline void JvmName(absl::string_view name, const JvmNameContext& context) {
0401   if (context.lite && !context.options.jvm_dsl) return;
0402   context.printer->Emit("@kotlin.jvm.JvmName(\"");
0403   // Note: `name` will likely have vars in it that we do want to interpolate.
0404   context.printer->Emit(name);
0405   context.printer->Emit("\")\n");
0406 }
0407 
0408 }  // namespace java
0409 }  // namespace compiler
0410 }  // namespace protobuf
0411 }  // namespace google
0412 
0413 #include "google/protobuf/port_undef.inc"
0414 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__