// 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_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__

#include <deque>
#include <google/protobuf/stubs/hash.h>
#include <string>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/util/internal/type_info.h>
#include <google/protobuf/util/internal/datapiece.h>
#include <google/protobuf/util/internal/error_listener.h>
#include <google/protobuf/util/internal/proto_writer.h>
#include <google/protobuf/util/internal/structured_objectwriter.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/bytestream.h>

namespace google {
namespace protobuf {
namespace io {
class CodedOutputStream;
}  // namespace io
}  // namespace protobuf


namespace protobuf {
class Type;
class Field;
}  // namespace protobuf


namespace protobuf {
namespace util {
namespace converter {

class ObjectLocationTracker;

// An ObjectWriter that can write protobuf bytes directly from writer events.
// This class supports all special types like Struct and Map. It uses
// the ProtoWriter class to write raw proto bytes.
//
// It also supports streaming.
class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter {
 public:
  // Options that control ProtoStreamObjectWriter class's behavior.
  struct Options {
    // Treats numeric inputs in google.protobuf.Struct as strings. Normally,
    // numeric values are returned in double field "number_value" of
    // google.protobuf.Struct. However, this can cause precision loss for
    // int64/uint64/double inputs. This option is provided for cases that want
    // to preserve number precision.
    //
    // TODO(skarvaje): Rename to struct_numbers_as_strings as it covers double
    // as well.
    bool struct_integers_as_strings;

    // Not treat unknown fields as an error. If there is an unknown fields,
    // just ignore it and continue to process the rest.
    bool ignore_unknown_fields;

    // If true, check if enum name in camel case or without underscore matches
    // the field name.
    bool use_lower_camel_for_enums;

    Options()
        : struct_integers_as_strings(false),
          ignore_unknown_fields(false),
          use_lower_camel_for_enums(false) {}

    // Default instance of Options with all options set to defaults.
    static const Options& Defaults() {
      static Options defaults;
      return defaults;
    }
  };

// Constructor. Does not take ownership of any parameter passed in.
  ProtoStreamObjectWriter(TypeResolver* type_resolver,
                          const google::protobuf::Type& type,
                          strings::ByteSink* output, ErrorListener* listener,
                          const ProtoStreamObjectWriter::Options& options =
                              ProtoStreamObjectWriter::Options::Defaults());
  virtual ~ProtoStreamObjectWriter();

  // ObjectWriter methods.
  virtual ProtoStreamObjectWriter* StartObject(StringPiece name);
  virtual ProtoStreamObjectWriter* EndObject();
  virtual ProtoStreamObjectWriter* StartList(StringPiece name);
  virtual ProtoStreamObjectWriter* EndList();

  // Renders a DataPiece 'value' into a field whose wire type is determined
  // from the given field 'name'.
  virtual ProtoStreamObjectWriter* RenderDataPiece(StringPiece name,
                                                   const DataPiece& value);

 protected:
  // Function that renders a well known type with modified behavior.
  typedef util::Status (*TypeRenderer)(ProtoStreamObjectWriter*,
                                         const DataPiece&);

  // Handles writing Anys out using nested object writers and the like.
  class LIBPROTOBUF_EXPORT AnyWriter {
   public:
    explicit AnyWriter(ProtoStreamObjectWriter* parent);
    ~AnyWriter();

    // Passes a StartObject call through to the Any writer.
    void StartObject(StringPiece name);

    // Passes an EndObject call through to the Any. Returns true if the any
    // handled the EndObject call, false if the Any is now all done and is no
    // longer needed.
    bool EndObject();

    // Passes a StartList call through to the Any writer.
    void StartList(StringPiece name);

    // Passes an EndList call through to the Any writer.
    void EndList();

    // Renders a data piece on the any.
    void RenderDataPiece(StringPiece name, const DataPiece& value);

   private:
    // Before the "@type" field is encountered, we store all incoming data
    // into this Event struct and replay them after we get the "@type" field.
    class LIBPROTOBUF_EXPORT Event {
     public:
      enum Type {
        START_OBJECT = 0,
        END_OBJECT = 1,
        START_LIST = 2,
        END_LIST = 3,
        RENDER_DATA_PIECE = 4,
      };

      // Constructor for END_OBJECT and END_LIST events.
      explicit Event(Type type) : type_(type), value_(DataPiece::NullData()) {}

      // Constructor for START_OBJECT and START_LIST events.
      explicit Event(Type type, StringPiece name)
          : type_(type),
            name_(name.ToString()),
            value_(DataPiece::NullData()) {}

      // Constructor for RENDER_DATA_PIECE events.
      explicit Event(StringPiece name, const DataPiece& value)
          : type_(RENDER_DATA_PIECE), name_(name.ToString()), value_(value) {
        DeepCopy();
      }

      Event(const Event& other)
          : type_(other.type_), name_(other.name_), value_(other.value_) {
        DeepCopy();
      }

      Event& operator=(const Event& other) {
        type_ = other.type_;
        name_ = other.name_;
        value_ = other.value_;
        DeepCopy();
        return *this;
      }

      void Replay(AnyWriter* writer) const;

     private:
      void DeepCopy();

      Type type_;
      string name_;
      DataPiece value_;
      string value_storage_;
    };

    // Handles starting up the any once we have a type.
    void StartAny(const DataPiece& value);

    // Writes the Any out to the parent writer in its serialized form.
    void WriteAny();

    // The parent of this writer, needed for various bits such as type info and
    // the listeners.
    ProtoStreamObjectWriter* parent_;

    // The nested object writer, used to write events.
    std::unique_ptr<ProtoStreamObjectWriter> ow_;

    // The type_url_ that this Any represents.
    string type_url_;

    // Whether this any is invalid. This allows us to only report an invalid
    // Any message a single time rather than every time we get a nested field.
    bool invalid_;

    // The output data and wrapping ByteSink.
    string data_;
    strings::StringByteSink output_;

    // The depth within the Any, so we can track when we're done.
    int depth_;

    // True if the type is a well-known type. Well-known types in Any
    // has a special formating:
    // {
    //   "@type": "type.googleapis.com/google.protobuf.XXX",
    //   "value": <JSON representation of the type>,
    // }
    bool is_well_known_type_;
    TypeRenderer* well_known_type_render_;

    // Store data before the "@type" field.
    std::vector<Event> uninterpreted_events_;
  };

  // Represents an item in a stack of items used to keep state between
  // ObjectWrier events.
  class LIBPROTOBUF_EXPORT Item : public BaseElement {
   public:
    // Indicates the type of item.
    enum ItemType {
      MESSAGE,  // Simple message
      MAP,      // Proto3 map type
      ANY,      // Proto3 Any type
    };

    // Constructor for the root item.
    Item(ProtoStreamObjectWriter* enclosing, ItemType item_type,
         bool is_placeholder, bool is_list);

    // Constructor for a field of a message.
    Item(Item* parent, ItemType item_type, bool is_placeholder, bool is_list);

    virtual ~Item() {}

    // These functions return true if the element type is corresponding to the
    // type in function name.
    bool IsMap() { return item_type_ == MAP; }
    bool IsAny() { return item_type_ == ANY; }

    AnyWriter* any() const { return any_.get(); }

    virtual Item* parent() const {
      return static_cast<Item*>(BaseElement::parent());
    }

    // Inserts map key into hash set if and only if the key did NOT already
    // exist in hash set.
    // The hash set (map_keys_) is ONLY used to keep track of map keys.
    // Return true if insert successfully; returns false if the map key was
    // already present.
    bool InsertMapKeyIfNotPresent(StringPiece map_key);

    bool is_placeholder() const { return is_placeholder_; }
    bool is_list() const { return is_list_; }

   private:
    // Used for access to variables of the enclosing instance of
    // ProtoStreamObjectWriter.
    ProtoStreamObjectWriter* ow_;

    // A writer for Any objects, handles all Any-related nonsense.
    std::unique_ptr<AnyWriter> any_;

    // The type of this element, see enum for permissible types.
    ItemType item_type_;

    // Set of map keys already seen for the type_. Used to validate incoming
    // messages so no map key appears more than once.
    std::unique_ptr<hash_set<string> > map_keys_;

    // Conveys whether this Item is a placeholder or not. Placeholder items are
    // pushed to stack to account for special types.
    bool is_placeholder_;

    // Conveys whether this Item is a list or not. This is used to send
    // StartList or EndList calls to underlying ObjectWriter.
    bool is_list_;

    GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(Item);
  };

  ProtoStreamObjectWriter(const TypeInfo* typeinfo,
                          const google::protobuf::Type& type,
                          strings::ByteSink* output, ErrorListener* listener);

  // Returns true if the field is a map.
  inline bool IsMap(const google::protobuf::Field& field);

  // Returns true if the field is an any.
  inline bool IsAny(const google::protobuf::Field& field);

  // Returns true if the field is google.protobuf.Struct.
  inline bool IsStruct(const google::protobuf::Field& field);

  // Returns true if the field is google.protobuf.Value.
  inline bool IsStructValue(const google::protobuf::Field& field);

  // Returns true if the field is google.protobuf.ListValue.
  inline bool IsStructListValue(const google::protobuf::Field& field);

  // Renders google.protobuf.Value in struct.proto. It picks the right oneof
  // type based on value's type.
  static util::Status RenderStructValue(ProtoStreamObjectWriter* ow,
                                          const DataPiece& value);

  // Renders google.protobuf.Timestamp value.
  static util::Status RenderTimestamp(ProtoStreamObjectWriter* ow,
                                        const DataPiece& value);

  // Renders google.protobuf.FieldMask value.
  static util::Status RenderFieldMask(ProtoStreamObjectWriter* ow,
                                        const DataPiece& value);

  // Renders google.protobuf.Duration value.
  static util::Status RenderDuration(ProtoStreamObjectWriter* ow,
                                       const DataPiece& value);

  // Renders wrapper message types for primitive types in
  // google/protobuf/wrappers.proto.
  static util::Status RenderWrapperType(ProtoStreamObjectWriter* ow,
                                          const DataPiece& value);

  static void InitRendererMap();
  static void DeleteRendererMap();
  static TypeRenderer* FindTypeRenderer(const string& type_url);

  // Returns true if the map key for type_ is not duplicated key.
  // If map key is duplicated key, this function returns false.
  // Note that caller should make sure that the current proto element (current_)
  // is of element type MAP or STRUCT_MAP.
  // It also calls the appropriate error callback and unnormalzied_name is used
  // for error string.
  bool ValidMapKey(StringPiece unnormalized_name);

  // Pushes an item on to the stack. Also calls either StartObject or StartList
  // on the underlying ObjectWriter depending on whether is_list is false or
  // not.
  // is_placeholder conveys whether the item is a placeholder item or not.
  // Placeholder items are pushed when adding auxillary types' StartObject or
  // StartList calls.
  void Push(StringPiece name, Item::ItemType item_type, bool is_placeholder,
            bool is_list);

  // Pops items from the stack. All placeholder items are popped until a
  // non-placeholder item is found.
  void Pop();

  // Pops one element from the stack. Calls EndObject() or EndList() on the
  // underlying ObjectWriter depending on the value of is_list_.
  void PopOneElement();

 private:
  // Helper functions to create the map and find functions responsible for
  // rendering well known types, keyed by type URL.
  static hash_map<string, TypeRenderer>* renderers_;

  // Variables for describing the structure of the input tree:
  // master_type_: descriptor for the whole protobuf message.
  const google::protobuf::Type& master_type_;

  // The current element, variable for internal state processing.
  std::unique_ptr<Item> current_;

  // Reference to the options that control this class's behavior.
  const ProtoStreamObjectWriter::Options options_;

  GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectWriter);
};

}  // namespace converter
}  // namespace util
}  // namespace protobuf

}  // namespace google
#endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
