// import.h -- Go frontend import declarations.     -*- 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_IMPORT_H
#define GO_IMPORT_H

#include "export.h"
#include "go-linemap.h"

class Gogo;
class Block;
class Package;
class Type;
class Named_object;
class Named_type;
class Expression;

// This class manages importing Go declarations.

class Import
{
 public:
  // The Stream class is an interface used to read the data.  The
  // caller should instantiate a child of this class.
  class Stream
  {
   public:
    Stream();
    virtual ~Stream();

    // Set the position, for error messages.
    void
    set_pos(int pos)
    { this->pos_ = pos; }

    // Return whether we have seen an error.
    bool
    saw_error() const
    { return this->saw_error_; }

    // Record that we've seen an error.
    void
    set_saw_error()
    { this->saw_error_ = true; }

    // Return the next character (a value from 0 to 0xff) without
    // advancing.  Returns -1 at end of stream.
    int
    peek_char();

    // Look for LENGTH characters, setting *BYTES to point to them.
    // Returns false if the bytes are not available.  Does not
    // advance.
    bool
    peek(size_t length, const char** bytes)
    { return this->do_peek(length, bytes); }

    // Return the next character (a value from 0 to 0xff) and advance
    // the read position by 1.  Returns -1 at end of stream.
    int
    get_char()
    {
      int c = this->peek_char();
      this->advance(1);
      return c;
    }

    // Return true if at the end of the stream.
    bool
    at_eof()
    { return this->peek_char() == -1; }

    // Return true if the next bytes match STR.
    bool
    match_c_string(const char* str)
    { return this->match_bytes(str, strlen(str)); }

    // Return true if the next LENGTH bytes match BYTES.
    bool
    match_bytes(const char* bytes, size_t length);

    // Give an error if the next bytes do not match STR.  Advance the
    // read position by the length of STR.
    void
    require_c_string(Location location, const char* str)
    { this->require_bytes(location, str, strlen(str)); }

    // Given an error if the next LENGTH bytes do not match BYTES.
    // Advance the read position by LENGTH.
    void
    require_bytes(Location, const char* bytes, size_t length);

    // Advance the read position by SKIP bytes.
    void
    advance(size_t skip)
    {
      this->do_advance(skip);
      this->pos_ += skip;
    }

    // Return the current read position.  This returns int because it
    // is more convenient in error reporting.  FIXME.
    int
    pos()
    { return static_cast<int>(this->pos_); }

   protected:
    // This function should set *BYTES to point to a buffer holding
    // the LENGTH bytes at the current read position.  It should
    // return false if the bytes are not available.  This should not
    // change the current read position.
    virtual bool
    do_peek(size_t length, const char** bytes) = 0;

    // This function should advance the current read position LENGTH
    // bytes.
    virtual void
    do_advance(size_t skip) = 0;

   private:
    // The current read position.
    size_t pos_;
    // True if we've seen an error reading from this stream.
    bool saw_error_;
  };

  // Find import data.  This searches the file system for FILENAME and
  // returns a pointer to a Stream object to read the data that it
  // exports.  LOCATION is the location of the import statement.
  // RELATIVE_IMPORT_PATH is used as a prefix for a relative import.
  static Stream*
  open_package(const std::string& filename, Location location,
	       const std::string& relative_import_path);

  // Constructor.
  Import(Stream*, Location);

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

  // Import everything defined in the stream.  LOCAL_NAME is the local
  // name to be used for bindings; if it is the string "." then
  // bindings should be inserted in the global scope.  If LOCAL_NAME
  // is the empty string then the name of the package itself is the
  // local name.  This returns the imported package, or NULL on error.
  Package*
  import(Gogo*, const std::string& local_name, bool is_local_name_exported);

  // The location of the import statement.
  Location
  location() const
  { return this->location_; }

  // Return the package we are importing.
  Package*
  package() const
  { return this->package_; }

  // Return the next character.
  int
  peek_char()
  { return this->stream_->peek_char(); }

  // Return the next character and advance.
  int
  get_char()
  { return this->stream_->get_char(); }

  // Read LENGTH characters into a string and advance past them.  On
  // EOF reports an error and returns an empty string.
  std::string
  read(size_t length);

  // Return true at the end of the stream.
  bool
  at_eof()
  { return this->stream_->at_eof(); }

  // Return whether the next bytes match STR.
  bool
  match_c_string(const char* str)
  { return this->stream_->match_c_string(str); }

  // Require that the next bytes match STR.
  void
  require_c_string(const char* str)
  { this->stream_->require_c_string(this->location_, str); }

  // Advance the stream SKIP bytes.
  void
  advance(size_t skip)
  { this->stream_->advance(skip); }

  // Skip a semicolon if using an older version.
  void
  require_semicolon_if_old_version()
  {
    if (this->version_ == EXPORT_FORMAT_V1
	|| this->version_ == EXPORT_FORMAT_V2)
      this->require_c_string(";");
  }

  // Read an identifier.
  std::string
  read_identifier();

  // Read a name.  This is like read_identifier, except that a "?" is
  // returned as an empty string.  This matches Export::write_name.
  std::string
  read_name();

  // Read a type.
  Type*
  read_type();

  // Read an escape note.
  std::string
  read_escape();

 private:
  static Stream*
  try_package_in_directory(const std::string&, Location);

  static int
  try_suffixes(std::string*);

  static Stream*
  find_export_data(const std::string& filename, int fd, Location);

  static Stream*
  find_object_export_data(const std::string& filename, int fd,
			  off_t offset, Location);

  static const int archive_magic_len = 8;

  static bool
  is_archive_magic(const char*);

  static Stream*
  find_archive_export_data(const std::string& filename, int fd,
			   Location);

  // Read a package line.
  void
  read_one_package();

  // Read an import line.
  void
  read_one_import();

  // Read an indirectimport line.
  void
  read_one_indirect_import();

  // Read the import control functions and init graph.
  void
  read_import_init_fns(Gogo*);

  // Read the types.
  bool
  read_types();

  // Import a constant.
  void
  import_const();

  // Import a type.
  void
  import_type();

  // Import a variable.
  void
  import_var();

  // Import a function.
  Named_object*
  import_func(Package*);

  // Parse a type definition.
  bool
  parse_type(int index);

  // Read a named type and store it at this->type_[index].
  Type*
  read_named_type(int index);

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

  // Get an integer from a string.
  bool
  string_to_int(const std::string&, bool is_neg_ok, int* ret);

  // Get an unsigned integer from a string.
  bool
  string_to_unsigned(const std::string& s, unsigned* ret)
  {
    int ivalue;
    if (!this->string_to_int(s, false, &ivalue))
      return false;
    *ret = static_cast<unsigned>(ivalue);
    return true;
  }

  // Return the version number of the export data we're reading.
  Export_data_version
  version() const { return this->version_; }

  // The general IR.
  Gogo* gogo_;
  // The stream from which to read import data.
  Stream* stream_;
  // The location of the import statement we are processing.
  Location location_;
  // The package we are importing.
  Package* package_;
  // Whether to add new objects to the global scope, rather than to a
  // package scope.
  bool add_to_globals_;
  // All type data.
  std::string type_data_;
  // Position of type data in the stream.
  int type_pos_;
  // Mapping from type code to offset/length in type_data_.
  std::vector<std::pair<size_t, size_t> > type_offsets_;
  // Mapping from negated builtin type codes to Type structures.
  std::vector<Named_type*> builtin_types_;
  // Mapping from exported type codes to Type structures.
  std::vector<Type*> types_;
  // Version of export data we're reading.
  Export_data_version version_;
};

// Read import data from a string.

class Stream_from_string : public Import::Stream
{
 public:
  Stream_from_string(const std::string& str)
    : str_(str), pos_(0)
  { }

 protected:
  bool
  do_peek(size_t length, const char** bytes)
  {
    if (this->pos_ + length > this->str_.length())
      return false;
    *bytes = this->str_.data() + this->pos_;
    return true;
  }

  void
  do_advance(size_t len)
  { this->pos_ += len; }

 private:
  // The string of data we are reading.
  std::string str_;
  // The current position within the string.
  size_t pos_;
};

// Read import data from a buffer allocated using malloc.

class Stream_from_buffer : public Import::Stream
{
 public:
  Stream_from_buffer(char* buf, size_t length)
    : buf_(buf), length_(length), pos_(0)
  { }

  ~Stream_from_buffer()
  { free(this->buf_); }

 protected:
  bool
  do_peek(size_t length, const char** bytes)
  {
    if (this->pos_ + length > this->length_)
      return false;
    *bytes = this->buf_ + this->pos_;
    return true;
  }

  void
  do_advance(size_t len)
  { this->pos_ += len; }

 private:
  // The data we are reading.
  char* buf_;
  // The length of the buffer.
  size_t length_;
  // The current position within the buffer.
  size_t pos_;
};

// Read import data from an open file descriptor.

class Stream_from_file : public Import::Stream
{
 public:
  Stream_from_file(int fd);

  ~Stream_from_file();

 protected:
  bool
  do_peek(size_t, const char**);

  void
  do_advance(size_t);

 private:
  // No copying.
  Stream_from_file(const Stream_from_file&);
  Stream_from_file& operator=(const Stream_from_file&);

  // The file descriptor.
  int fd_;
  // Data read from the file.
  std::string data_;
};

// Read import data from an offset into a std::string.  This uses a
// reference to the string, to avoid copying, so the string must be
// kept alive through some other mechanism.

class Stream_from_string_ref : public Import::Stream
{
 public:
  Stream_from_string_ref(const std::string& str, size_t offset, size_t length)
    : str_(str), pos_(offset), end_(offset + length)
  { }

  ~Stream_from_string_ref()
  {}

 protected:
  bool
  do_peek(size_t length, const char** bytes)
  {
    if (this->pos_ + length > this->end_)
      return false;
    *bytes = &this->str_[this->pos_];
    return true;
  }

  void
  do_advance(size_t length)
  { this->pos_ += length; }

 private:
  // A reference to the string we are reading from.
  const std::string& str_;
  // The current offset into the string.
  size_t pos_;
  // The index after the last byte we can read.
  size_t end_;
};

// Class to manage importing a function body.  This is passed around
// to Statements and Expressions.  It parses the function into the IR.

class Import_function_body
{
 public:
  Import_function_body(Gogo* gogo, Location loc, Named_object* named_object,
		       const std::string& body, size_t off, Block* block,
		       int indent)
    : gogo_(gogo), loc_(loc), named_object_(named_object), body_(body),
      off_(off), block_(block), indent_(indent)
  { }

  // The IR.
  Gogo*
  gogo()
  { return this->gogo_; }

  // The location to report in an error message.
  Location
  location() const
  { return this->loc_; }

  // A reference to the body we are reading.
  const std::string&
  body() const
  { return this->body_; }

  // The current offset into the body.
  size_t
  off()
  { return this->off_; }

  // Update the offset into the body.
  void
  set_off(size_t off)
  { this->off_ = off; }

  // The current block.
  Block*
  block()
  { return this->block_; }

  // The current indentation.
  int
  indent() const
  { return this->indent_; }

  // The name of the function we are parsing.
  const std::string&
  name() const;

 private:
  // The IR.
  Gogo* gogo_;
  // The location to report in an error message.
  Location loc_;
  // The function we are parsing.
  Named_object* named_object_;
  // The exported data we are parsing.  Note that this is a reference;
  // the body string must laster longer than this object.
  const std::string& body_;
  // The current offset into body_.
  size_t off_;
  // Current block.
  Block* block_;
  // Current expected indentation level.
  int indent_;
};

#endif // !defined(GO_IMPORT_H)
