// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__

#include <cstdint>
#include <string>

#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/descriptor.pb.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace java {

// Commonly-used separator comments.  Thick is a line of '=', thin is a line
// of '-'.
extern const char kThickSeparator[];
extern const char kThinSeparator[];

bool IsForbiddenKotlin(const std::string& field_name);

// If annotation_file is non-empty, prints a javax.annotation.Generated
// annotation to the given Printer. annotation_file will be referenced in the
// annotation's comments field. delimiter should be the Printer's delimiter
// character. annotation_file will be included verbatim into a Java literal
// string, so it should not contain quotes or invalid Java escape sequences;
// however, these are unlikely to appear in practice, as the value of
// annotation_file should be generated from the filename of the source file
// being annotated (which in turn must be a Java identifier plus ".java").
void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$',
                              const std::string& annotation_file = "");

// If a GeneratedMessageLite contains non-lite enums, then its verifier
// must be instantiated inline, rather than retrieved from the enum class.
void PrintEnumVerifierLogic(io::Printer* printer,
                            const FieldDescriptor* descriptor,
                            const std::map<std::string, std::string>& variables,
                            const char* var_name,
                            const char* terminating_string, bool enforce_lite);

// Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter.
std::string ToCamelCase(const std::string& input, bool lower_first);

char ToUpperCh(char ch);
char ToLowerCh(char ch);

// Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter.
std::string UnderscoresToCamelCase(const std::string& name,
                                   bool cap_first_letter);
// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
// "fooBarBaz" or "FooBarBaz", respectively.
std::string UnderscoresToCamelCase(const FieldDescriptor* field);
std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);

// Similar, but for method names.  (Typically, this merely has the effect
// of lower-casing the first letter of the name.)
std::string UnderscoresToCamelCase(const MethodDescriptor* method);

// Same as UnderscoresToCamelCase, but checks for reserved keywords
std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field);

// Similar to UnderscoresToCamelCase, but guarantees that the result is a
// complete Java identifier by adding a _ if needed.
std::string CamelCaseFieldName(const FieldDescriptor* field);

// Get an identifier that uniquely identifies this type within the file.
// This is used to declare static variables related to this type at the
// outermost file scope.
std::string UniqueFileScopeIdentifier(const Descriptor* descriptor);

// Gets the unqualified class name for the file.  For each .proto file, there
// will be one Java class containing all the immutable messages and another
// Java class containing all the mutable messages.
// TODO(xiaofeng): remove the default value after updating client code.
std::string FileClassName(const FileDescriptor* file, bool immutable = true);

// Returns the file's Java package name.
std::string FileJavaPackage(const FileDescriptor* file, bool immutable);

// Returns output directory for the given package name.
std::string JavaPackageToDir(std::string package_name);

// Comma-separate list of option-specified interfaces implemented by the
// Message, to follow the "implements" declaration of the Message definition.
std::string ExtraMessageInterfaces(const Descriptor* descriptor);
// Comma-separate list of option-specified interfaces implemented by the
// MutableMessage, to follow the "implements" declaration of the MutableMessage
// definition.
std::string ExtraMutableMessageInterfaces(const Descriptor* descriptor);
// Comma-separate list of option-specified interfaces implemented by the
// Builder, to follow the "implements" declaration of the Builder definition.
std::string ExtraBuilderInterfaces(const Descriptor* descriptor);
// Comma-separate list of option-specified interfaces extended by the
// MessageOrBuilder, to follow the "extends" declaration of the
// MessageOrBuilder definition.
std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor);

// Get the unqualified Java class name for mutable messages. i.e. without
// package or outer classnames.
inline std::string ShortMutableJavaClassName(const Descriptor* descriptor) {
  return descriptor->name();
}

// Whether the given descriptor is for one of the core descriptor protos. We
// cannot currently use the new runtime with core protos since there is a
// bootstrapping problem with obtaining their descriptors.
inline bool IsDescriptorProto(const Descriptor* descriptor) {
  return descriptor->file()->name() == "net/proto2/proto/descriptor.proto" ||
         descriptor->file()->name() == "google/protobuf/descriptor.proto";
}

// Returns the stored type string used by the experimental runtime for oneof
// fields.
std::string GetOneofStoredType(const FieldDescriptor* field);

// We use either the proto1 enums if the enum is generated, otherwise fall back
// to use integers.
enum class Proto1EnumRepresentation {
  kEnum,
  kInteger,
};

// Returns which representation we should use.
inline Proto1EnumRepresentation GetProto1EnumRepresentation(
    const EnumDescriptor* descriptor) {
  if (descriptor->containing_type() != nullptr) {
    return Proto1EnumRepresentation::kEnum;
  }
  return Proto1EnumRepresentation::kInteger;
}

// Whether we should generate multiple java files for messages.
inline bool MultipleJavaFiles(const FileDescriptor* descriptor,
                              bool immutable) {
  (void)immutable;
  return descriptor->options().java_multiple_files();
}


// Returns true if `descriptor` will be written to its own .java file.
// `immutable` should be set to true if we're generating for the immutable API.
template <typename Descriptor>
bool IsOwnFile(const Descriptor* descriptor, bool immutable) {
  return descriptor->containing_type() == NULL &&
         MultipleJavaFiles(descriptor->file(), immutable);
}

template <>
inline bool IsOwnFile(const ServiceDescriptor* descriptor, bool immutable) {
  return MultipleJavaFiles(descriptor->file(), immutable);
}

// If `descriptor` describes an object with its own .java file,
// returns the name (relative to that .java file) of the file that stores
// annotation data for that descriptor. `suffix` is usually empty, but may
// (e.g.) be "OrBuilder" for some generated interfaces.
template <typename Descriptor>
std::string AnnotationFileName(const Descriptor* descriptor,
                               const std::string& suffix) {
  return descriptor->name() + suffix + ".java.pb.meta";
}

template <typename Descriptor>
void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer,
                                   Descriptor* descriptor, bool immutable,
                                   const std::string& suffix = "") {
  if (IsOwnFile(descriptor, immutable)) {
    PrintGeneratedAnnotation(printer, '$',
                             context->options().annotate_code
                                 ? AnnotationFileName(descriptor, suffix)
                                 : "");
  }
}

// Get the unqualified name that should be used for a field's field
// number constant.
std::string FieldConstantName(const FieldDescriptor* field);

// Returns the type of the FieldDescriptor.
// This does nothing interesting for the open source release, but is used for
// hacks that improve compatibility with version 1 protocol buffers at Google.
FieldDescriptor::Type GetType(const FieldDescriptor* field);

enum JavaType {
  JAVATYPE_INT,
  JAVATYPE_LONG,
  JAVATYPE_FLOAT,
  JAVATYPE_DOUBLE,
  JAVATYPE_BOOLEAN,
  JAVATYPE_STRING,
  JAVATYPE_BYTES,
  JAVATYPE_ENUM,
  JAVATYPE_MESSAGE
};

JavaType GetJavaType(const FieldDescriptor* field);

const char* PrimitiveTypeName(JavaType type);

// Get the fully-qualified class name for a boxed primitive type, e.g.
// "java.lang.Integer" for JAVATYPE_INT.  Returns NULL for enum and message
// types.
const char* BoxedPrimitiveTypeName(JavaType type);

// Kotlin source does not distinguish between primitives and non-primitives,
// but does use Kotlin-specific qualified types for them.
const char* KotlinTypeName(JavaType type);

// Get the name of the java enum constant representing this type. E.g.,
// "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full
// name is "com.google.protobuf.WireFormat.FieldType.INT32".
const char* FieldTypeName(const FieldDescriptor::Type field_type);

class ClassNameResolver;
std::string DefaultValue(const FieldDescriptor* field, bool immutable,
                         ClassNameResolver* name_resolver);
inline std::string ImmutableDefaultValue(const FieldDescriptor* field,
                                         ClassNameResolver* name_resolver) {
  return DefaultValue(field, true, name_resolver);
}
bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field);

// Does this message class have descriptor and reflection methods?
inline bool HasDescriptorMethods(const Descriptor* /* descriptor */,
                                 bool enforce_lite) {
  return !enforce_lite;
}
inline bool HasDescriptorMethods(const EnumDescriptor* /* descriptor */,
                                 bool enforce_lite) {
  return !enforce_lite;
}
inline bool HasDescriptorMethods(const FileDescriptor* /* descriptor */,
                                 bool enforce_lite) {
  return !enforce_lite;
}

// Should we generate generic services for this file?
inline bool HasGenericServices(const FileDescriptor* file, bool enforce_lite) {
  return file->service_count() > 0 &&
         HasDescriptorMethods(file, enforce_lite) &&
         file->options().java_generic_services();
}

// Methods for shared bitfields.

// Gets the name of the shared bitfield for the given index.
std::string GetBitFieldName(int index);

// Gets the name of the shared bitfield for the given bit index.
// Effectively, GetBitFieldName(bitIndex / 32)
std::string GetBitFieldNameForBit(int bitIndex);

// Generates the java code for the expression that returns the boolean value
// of the bit of the shared bitfields for the given bit index.
// Example: "((bitField1_ & 0x04) == 0x04)"
std::string GenerateGetBit(int bitIndex);

// Generates the java code for the expression that sets the bit of the shared
// bitfields for the given bit index.
// Example: "bitField1_ = (bitField1_ | 0x04)"
std::string GenerateSetBit(int bitIndex);

// Generates the java code for the expression that clears the bit of the shared
// bitfields for the given bit index.
// Example: "bitField1_ = (bitField1_ & ~0x04)"
std::string GenerateClearBit(int bitIndex);

// Does the same as GenerateGetBit but operates on the bit field on a local
// variable. This is used by the builder to copy the value in the builder to
// the message.
// Example: "((from_bitField1_ & 0x04) == 0x04)"
std::string GenerateGetBitFromLocal(int bitIndex);

// Does the same as GenerateSetBit but operates on the bit field on a local
// variable. This is used by the builder to copy the value in the builder to
// the message.
// Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
std::string GenerateSetBitToLocal(int bitIndex);

// Does the same as GenerateGetBit but operates on the bit field on a local
// variable. This is used by the parsing constructor to record if a repeated
// field is mutable.
// Example: "((mutable_bitField1_ & 0x04) == 0x04)"
std::string GenerateGetBitMutableLocal(int bitIndex);

// Does the same as GenerateSetBit but operates on the bit field on a local
// variable. This is used by the parsing constructor to record if a repeated
// field is mutable.
// Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
std::string GenerateSetBitMutableLocal(int bitIndex);

// Returns whether the JavaType is a reference type.
bool IsReferenceType(JavaType type);

// Returns the capitalized name for calling relative functions in
// CodedInputStream
const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable);

// For encodings with fixed sizes, returns that size in bytes.  Otherwise
// returns -1.
int FixedSize(FieldDescriptor::Type type);

// Comparators used to sort fields in MessageGenerator
struct FieldOrderingByNumber {
  inline bool operator()(const FieldDescriptor* a,
                         const FieldDescriptor* b) const {
    return a->number() < b->number();
  }
};

struct ExtensionRangeOrdering {
  bool operator()(const Descriptor::ExtensionRange* a,
                  const Descriptor::ExtensionRange* b) const {
    return a->start < b->start;
  }
};

// Sort the fields of the given Descriptor by number into a new[]'d array
// and return it. The caller should delete the returned array.
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);

// Does this message class have any packed fields?
inline bool HasPackedFields(const Descriptor* descriptor) {
  for (int i = 0; i < descriptor->field_count(); i++) {
    if (descriptor->field(i)->is_packed()) {
      return true;
    }
  }
  return false;
}

// Check a message type and its sub-message types recursively to see if any of
// them has a required field. Return true if a required field is found.
bool HasRequiredFields(const Descriptor* descriptor);

inline bool IsProto2(const FileDescriptor* descriptor) {
  return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
}

inline bool IsRealOneof(const FieldDescriptor* descriptor) {
  return descriptor->containing_oneof() &&
         !descriptor->containing_oneof()->is_synthetic();
}

inline bool HasHazzer(const FieldDescriptor* descriptor) {
  return !descriptor->is_repeated() &&
         (descriptor->message_type() || descriptor->has_optional_keyword() ||
          IsProto2(descriptor->file()) || IsRealOneof(descriptor));
}

inline bool HasHasbit(const FieldDescriptor* descriptor) {
  // Note that currently message fields inside oneofs have hasbits. This is
  // surprising, as the oneof case should avoid any need for a hasbit. But if
  // you change this method to remove hasbits for oneofs, a few tests fail.
  // TODO(b/124347790): remove hasbits for oneofs
  return !descriptor->is_repeated() &&
         (descriptor->has_optional_keyword() || IsProto2(descriptor->file()));
}

// Whether generate classes expose public PARSER instances.
inline bool ExposePublicParser(const FileDescriptor* descriptor) {
  // TODO(liujisi): Mark the PARSER private in 3.1.x releases.
  return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
}

// Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet
// but in the message and can be queried using additional getters that return
// ints.
inline bool SupportUnknownEnumValue(const FileDescriptor* descriptor) {
  return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
}

inline bool SupportUnknownEnumValue(const FieldDescriptor* field) {
  return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
}

// Check whether a message has repeated fields.
bool HasRepeatedFields(const Descriptor* descriptor);

inline bool IsMapEntry(const Descriptor* descriptor) {
  return descriptor->options().map_entry();
}

inline bool IsMapField(const FieldDescriptor* descriptor) {
  return descriptor->is_map();
}

inline bool IsAnyMessage(const Descriptor* descriptor) {
  return descriptor->full_name() == "google.protobuf.Any";
}

inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) {
  return descriptor->name() == "google/protobuf/wrappers.proto";
}

inline bool CheckUtf8(const FieldDescriptor* descriptor) {
  return descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
         descriptor->file()->options().java_string_check_utf8();
}

inline std::string GeneratedCodeVersionSuffix() {
  return "V3";
}

void WriteUInt32ToUtf16CharSequence(uint32_t number,
                                    std::vector<uint16_t>* output);

inline void WriteIntToUtf16CharSequence(int value,
                                        std::vector<uint16_t>* output) {
  WriteUInt32ToUtf16CharSequence(static_cast<uint32_t>(value), output);
}

// Escape a UTF-16 character so it can be embedded in a Java string literal.
void EscapeUtf16ToString(uint16_t code, std::string* output);

// Only the lowest two bytes of the return value are used. The lowest byte
// is the integer value of a j/c/g/protobuf/FieldType enum. For the other
// byte:
//    bit 0: whether the field is required.
//    bit 1: whether the field requires UTF-8 validation.
//    bit 2: whether the field needs isInitialized check.
//    bit 3: whether the field is a map field with proto2 enum value.
//    bits 4-7: unused
int GetExperimentalJavaFieldType(const FieldDescriptor* field);

// To get the total number of entries need to be built for experimental runtime
// and the first field number that are not in the table part
std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber(
    const FieldDescriptor** fields, int count);
}  // namespace java
}  // namespace compiler
}  // namespace protobuf
}  // namespace google

#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
