// export.h -- Export declarations in Go frontend.     -*- C++ -*-

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef GO_EXPORT_H
#define GO_EXPORT_H

#include "string-dump.h"

class Go_sha1_helper;
class Gogo;
class Named_object;
class Export_function_body;
class Import_init;
class Named_object;
class Bindings;
class Type;
class Package;
class Import_init_set;
class Backend;
class Temporary_statement;
class Unnamed_label;
struct Export_impl;

// Codes used for the builtin types.  These are all negative to make
// them easily distinct from the codes assigned by Export::write_type.
// Note that these codes may not be changed!  Changing them would
// break existing export data.

enum Builtin_code
{
  BUILTIN_INT8 = -1,
  BUILTIN_INT16 = -2,
  BUILTIN_INT32 = -3,
  BUILTIN_INT64 = -4,
  BUILTIN_UINT8 = -5,
  BUILTIN_UINT16 = -6,
  BUILTIN_UINT32 = -7,
  BUILTIN_UINT64 = -8,
  BUILTIN_FLOAT32 = -9,
  BUILTIN_FLOAT64 = -10,
  BUILTIN_INT = -11,
  BUILTIN_UINT = -12,
  BUILTIN_UINTPTR = -13,
  BUILTIN_BOOL = -15,
  BUILTIN_STRING = -16,
  BUILTIN_COMPLEX64 = -17,
  BUILTIN_COMPLEX128 = -18,
  BUILTIN_ERROR = -19,
  BUILTIN_BYTE = -20,
  BUILTIN_RUNE = -21,

  SMALLEST_BUILTIN_CODE = -21
};

// Export data version number. New export data is written with the
// "current" version, but there is support for reading files with
// older version export data (at least for now).

enum Export_data_version {
  EXPORT_FORMAT_UNKNOWN = 0,
  EXPORT_FORMAT_V1 = 1,
  EXPORT_FORMAT_V2 = 2,
  EXPORT_FORMAT_V3 = 3,
  EXPORT_FORMAT_CURRENT = EXPORT_FORMAT_V3
};

// This class manages exporting Go declarations.  It handles the main
// loop of exporting.  A pointer to this class is also passed to the
// various specific export implementations.

class Export : public String_dump
{
 public:
  // The Stream class is an interface used to output the exported
  // information.  The caller should instantiate a child of this
  // class.
  class Stream
  {
   public:
    Stream();
    virtual ~Stream();

    // Write a string. Implements the String_dump interface.
    void
    write_string(const std::string& s)
    { this->write_and_sum_bytes(s.data(), s.length()); }

    // Write a nul terminated string. Implements the String_dump interface.
    void
    write_c_string(const char* s)
    { this->write_and_sum_bytes(s, strlen(s)); }

    // Write some bytes.
    void
    write_bytes(const char* bytes, size_t length)
    { this->write_and_sum_bytes(bytes, length); }

    // Return the raw bytes of the checksum data.
    std::string
    checksum();

    // Write a checksum string to the stream.  This will be called at
    // the end of the other output.
    void
    write_checksum(const std::string&);

   protected:
    // This function is called with data to export.  This data must be
    // made available as a contiguous stream for the importer.
    virtual void
    do_write(const char* bytes, size_t length) = 0;

  private:
    void
    write_and_sum_bytes(const char*, size_t);

    // The checksum helper.
    Go_sha1_helper* sha1_helper_;
  };

  Export(Stream*);
  ~Export();

  // Size of export data magic string (which includes version number).
  static const int magic_len = 4;

  // Magic strings (current version and older versions).
  static const char cur_magic[magic_len];
  static const char v1_magic[magic_len];
  static const char v2_magic[magic_len];

  // The length of the checksum string.
  static const int checksum_len = 20;

  // Register the builtin types.
  void
  register_builtin_types(Gogo*);

  // Export the identifiers in BINDINGS which are marked for export.
  // The exporting is done via a series of calls to THIS->STREAM_.  If
  // is nothing to export, this->stream_->write will not be called.
  // PREFIX is the package prefix.  PKGPATH is the package path.
  // Only one of PREFIX and PKGPATH will be non-empty.
  // PACKAGES is all the packages we have seen.
  // IMPORTS is the explicitly imported packages.
  // IMPORT_INIT_FN is the name of the import initialization function
  // for this package; it will be empty if none is needed.
  // IMPORTED_INIT_FNS is the list of initialization functions for
  // imported packages.
  void
  export_globals(const std::string& package_name,
		 const std::string& prefix,
		 const std::string& pkgpath,
		 const std::map<std::string, Package*>& packages,
		 const std::map<std::string, Package*>& imports,
		 const std::string& import_init_fn,
		 const Import_init_set& imported_init_fns,
		 const Bindings* bindings,
                 Unordered_set(Named_object*)* marked_inline_functions);

  // Record a type that is mentioned in export data. Return value is
  // TRUE for newly visited types, FALSE for types that have been seen
  // previously.
  bool
  record_type(Type*);

  // Assign type indices to types mentioned in export data.
  int
  assign_type_indices(const std::vector<Named_object*>& sorted_exports);

  // Write a string to the export stream.
  void
  write_string(const std::string& s)
  { this->stream_->write_string(s); }

  // Write a nul terminated string to the export stream.
  void
  write_c_string(const char* s)
  { this->stream_->write_c_string(s); }

  // Write some bytes to the export stream.
  void
  write_bytes(const char* bytes, size_t length)
  { this->stream_->write_bytes(bytes, length); }

  // Write a name to the export stream.  If NAME is empty, write "?".
  void
  write_name(const std::string& name);

  // Write out a type.  This handles references back to previous
  // definitions.
  void
  write_type(const Type*);

  // Write a type to an exported function body.
  void
  write_type_to(const Type*, Export_function_body*);

  // Write the escape note to the export stream.  If NOTE is NULL, write
  // nothing.
  void
  write_escape(std::string* note);

  // Write an integer value.
  void
  write_int(int);

  // Write an unsigned value.
  void
  write_unsigned(unsigned);

  // Return the index of a package.
  int
  package_index(const Package* p) const;

  // Return the index of the "unsafe" package, which must be one of
  // the exported packages.
  int
  unsafe_package_index() const;

 private:
  Export(const Export&);
  Export& operator=(const Export&);

  // Write out all known packages.
  void
  write_packages(const std::map<std::string, Package*>& packages);

  typedef std::map<unsigned, std::set<unsigned> > Init_graph;

  static void
  add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink);

  static void
  populate_init_graph(Init_graph* init_graph,
                      const Import_init_set& imported_init_fns,
                      const std::map<std::string, unsigned>& init_idx);

  // Write out the imported packages.
  void
  write_imports(const std::map<std::string, Package*>& imports,
		const Unordered_set(const Package*)& type_imports);

  // Write out the imported initialization functions and init graph.
  void
  write_imported_init_fns(const std::string& package_name,
			  const std::string&, const Import_init_set&);

  // Write out all types.
  void
  write_types(int unexported_type_index);

  // Write out one type definition.
  void
  write_type_definition(const Type* type, int index);

  // Register one builtin type.
  void
  register_builtin_type(Gogo*, const char* name, Builtin_code);

  // Return the index of a type in the export data.
  int
  type_index(const Type*);

  // Set the index of a type.
  void
  set_type_index(const Type*);

  // The stream to which we are writing data.
  Stream* stream_;
  // Index number of next type.
  int type_index_;
  // Packages we have written out.
  Unordered_map(const Package*, int) packages_;
  // Hidden implementation-specific state.
  Export_impl* impl_;
};

// An export streamer that puts the export stream in a named section.

class Stream_to_section : public Export::Stream
{
 public:
  Stream_to_section(Backend*);

 protected:
  void
  do_write(const char*, size_t);

 private:
  Backend* backend_;
};

// An export streamer that puts the export stream in a string.

class Stream_to_string : public Export::Stream
{
 public:
  Stream_to_string()
    : string_()
  {}

  const std::string&
  string() const
  { return this->string_; }

 protected:
  void
  do_write(const char* s, size_t len)
  { this->string_.append(s, len); }

 private:
  std::string string_;
};

// Class to manage exporting a function body.  This is passed around
// to Statements and Expressions.  It builds up the export data for
// the function.

class Export_function_body : public String_dump
{
 public:
  Export_function_body(Export* exp, int indent)
    : exp_(exp), body_(), type_context_(NULL), next_temporary_index_(0),
      temporary_indexes_(), next_label_index_(0), label_indexes_(),
      indent_(indent)
  { }

  // Write a character to the body.
  void
  write_char(char c)
  { this->body_.append(1, c); }

  // Write a NUL terminated string to the body.
  void
  write_c_string(const char* str)
  { this->body_.append(str); }

  // Write a string to the body.
  void
  write_string(const std::string& str)
  { this->body_.append(str); }

  // Write a type reference to the body.
  void
  write_type(const Type* type)
  { this->exp_->write_type_to(type, this); }

  // Return the current type context.
  Type*
  type_context() const
  { return this->type_context_; }

  // Set the current type context.
  void
  set_type_context(Type* type)
  { this->type_context_ = type; }

  // Append as many spaces as the current indentation level.
  void
  indent()
  {
    for (int i = this->indent_; i > 0; i--)
      this->write_char(' ');
  }

  // Increment the indentation level.
  void
  increment_indent()
  { ++this->indent_; }

  // Decrement the indentation level.
  void
  decrement_indent()
  { --this->indent_; }

  // Return the index of a package.
  int
  package_index(const Package* p) const
  { return this->exp_->package_index(p); }

  // Return the index of the "unsafe" package.
  int
  unsafe_package_index() const
  { return this->exp_->unsafe_package_index(); }

  // Record a temporary statement and return its index.
  unsigned int
  record_temporary(const Temporary_statement*);

  // Return the index of a temporary statement.
  unsigned int
  temporary_index(const Temporary_statement*);

  // Return the index of an unnamed label.  If it doesn't already have
  // an index, give it one.
  unsigned int
  unnamed_label_index(const Unnamed_label*);

  // Return a reference to the completed body.
  const std::string&
  body() const
  { return this->body_; }

 private:
  // The overall export data.
  Export* exp_;
  // The body we are building.
  std::string body_;
  // Current type context.  Used to avoid duplicate type conversions.
  Type* type_context_;
  // Index to give to next temporary statement.
  unsigned int next_temporary_index_;
  // Map temporary statements to indexes.
  Unordered_map(const Temporary_statement*, unsigned int) temporary_indexes_;
  // Index to give to the next unnamed label.
  unsigned int next_label_index_;
  // Map unnamed labels to indexes.
  Unordered_map(const Unnamed_label*, unsigned int) label_indexes_;
  // Current indentation level: the number of spaces before each statement.
  int indent_;
};

#endif // !defined(GO_EXPORT_H)
