// 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.

#ifndef GOOGLE_PROTOBUF_UTIL_UNKNOWN_ENUM_IMPL_H__
#define GOOGLE_PROTOBUF_UTIL_UNKNOWN_ENUM_IMPL_H__

#include <stdlib.h>

#include <google/protobuf/stubs/common.h>
#include "net/proto/tagmapper.h"
#include <google/protobuf/bridge/compatibility_mode_support.h>

namespace google {
namespace protobuf {

// google/protobuf/message.h
class Message;

namespace util {

// NOTE: You should not call these functions directly.  Instead use either
// HAS_UNKNOWN_ENUM() or GET_UNKNOWN_ENUM(), defined in the public header.
// The macro-versions operate in a type-safe manner and behave appropriately
// for the proto version of the message, whereas these versions assume a
// specific proto version and allow the caller to pass in any arbitrary integer
// value as a field number.
//
// Returns whether the message has unrecognized the enum value for a given
// field. It also stores the value into the unknown_value parameter if the
// function returns true and the pointer is not NULL.
//
// In proto2, invalid enum values will be treated as unknown fields. This
// function checks that case.
bool HasUnknownEnum(const Message& message, int32 field_number,
                    int32* unknown_value = nullptr);
// Same as above, but returns all unknown enums.
bool GetRepeatedEnumUnknowns(const Message& message, int32 field_number,
                             vector<int32>* unknown_values = nullptr);
// In proto1, invalue enum values are stored in the same way as valid enum
// values.
// TODO(karner): Delete this once the migration to proto2 is complete.
bool HasUnknownEnumProto1(const Message& message, int32 field_number,
                          int32* unknown_value);
// Same as above, but returns all unknown enums.
bool GetRepeatedEnumUnknownsProto1(const Message& message, int32 field_number,
                                   vector<int32>* unknown_values);
// Invokes the appropriate version based on whether the message is proto1
// or proto2.
template <typename T>
bool HasUnknownEnum_Template(const T& message, int32 field_number,
                             int32* unknown_value = nullptr) {
  if (internal::is_base_of<bridge::internal::Proto1CompatibleMessage, T>::value ||
      !internal::is_base_of<ProtocolMessage, T>::value) {
    return HasUnknownEnum(message, field_number, unknown_value);
  } else {
    return HasUnknownEnumProto1(message, field_number, unknown_value);
  }
}
// Invokes the appropriate version based on whether the message is proto1
// or proto2.
template <typename T>
bool GetRepeatedEnumUnknowns_Template(
    const T& message, int32 field_number,
    vector<int32>* unknown_values = nullptr) {
  if (internal::is_base_of<bridge::internal::Proto1CompatibleMessage, T>::value ||
      !internal::is_base_of<ProtocolMessage, T>::value) {
    return GetRepeatedEnumUnknowns(message, field_number, unknown_values);
  } else {
    return GetRepeatedEnumUnknownsProto1(message, field_number,
                                         unknown_values);
  }
}

// NOTE: You should not call these functions directly.  Instead use
// CLEAR_UNKNOWN_ENUM(), defined in the public header.  The macro-versions
// operate in a type-safe manner and behave appropriately for the proto
// version of the message, whereas these versions assume a specific proto
// version and allow the caller to pass in any arbitrary integer value as a
// field number.
//
// Clears the unknown entries of the given field of the message.
void ClearUnknownEnum(Message* message, int32 field_number);
// In proto1, clears the field if the value is out of range.
// TODO(karner): Delete this or make it proto2-only once the migration
// to proto2 is complete.
void ClearUnknownEnumProto1(Message* message, int32 field_number);
template <typename T>
void ClearUnknownEnum_Template(T* message, int32 field_number) {
  if (internal::is_base_of<bridge::internal::Proto1CompatibleMessage, T>::value ||
      !internal::is_base_of<ProtocolMessage, T>::value) {
    ClearUnknownEnum(message, field_number);
  } else {
    ClearUnknownEnumProto1(message, field_number);
  }
}

// NOTE: You should not call these functions directly.  Instead use
// SET_UNKNOWN_ENUM(), defined in the public header.  The macro-versions
// operate in a type-safe manner and behave appropriately for the proto
// version of the message, whereas these versions assume a specific proto
// version and allow the caller to pass in any arbitrary integer value as a
// field number.
//
// Sets the given value in the unknown fields of the message.
void SetUnknownEnum(Message* message, int32 field_number, int32 unknown_value);
// In proto1, invalue enum values are stored in the same way as valid enum
// values.
// TODO(karner): Delete this once the migration to proto2 is complete.
void SetUnknownEnumProto1(Message* message, int32 field_number,
                          int32 unknown_value);
// Invokes the appropriate version based on whether the message is proto1
// or proto2.
template <typename T>
void SetUnknownEnum_Template(T* message, int32 field_number,
                             int32 unknown_value) {
  if (internal::is_base_of<bridge::internal::Proto1CompatibleMessage, T>::value ||
      !internal::is_base_of<ProtocolMessage, T>::value) {
    SetUnknownEnum(message, field_number, unknown_value);
  } else {
    SetUnknownEnumProto1(message, field_number, unknown_value);
  }
}

}  // namespace util
}  // namespace protobuf

}  // namespace google
#endif  // GOOGLE_PROTOBUF_UTIL_UNKNOWN_ENUM_IMPL_H__
