/* go-convert-interface.c -- convert interfaces for Go.

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

#include "runtime.h"
#include "go-alloc.h"
#include "go-assert.h"
#include "go-panic.h"
#include "go-string.h"
#include "go-type.h"
#include "interface.h"

/* This is called when converting one interface type into another
   interface type.  LHS_DESCRIPTOR is the type descriptor of the
   resulting interface.  RHS_DESCRIPTOR is the type descriptor of the
   object being converted.  This builds and returns a new interface
   method table.  If any method in the LHS_DESCRIPTOR interface is not
   implemented by the object, the conversion fails.  If the conversion
   fails, then if MAY_FAIL is true this returns NULL; otherwise, it
   panics.  */

void *
__go_convert_interface_2 (const struct __go_type_descriptor *lhs_descriptor,
			  const struct __go_type_descriptor *rhs_descriptor,
			  _Bool may_fail)
{
  const struct __go_interface_type *lhs_interface;
  int lhs_method_count;
  const struct __go_interface_method* lhs_methods;
  const void **methods;
  const struct __go_uncommon_type *rhs_uncommon;
  int rhs_method_count;
  const struct __go_method *p_rhs_method;
  int i;

  if (rhs_descriptor == NULL)
    {
      /* A nil value always converts to nil.  */
      return NULL;
    }

  __go_assert (lhs_descriptor->__code == GO_INTERFACE);
  lhs_interface = (const struct __go_interface_type *) lhs_descriptor;
  lhs_method_count = lhs_interface->__methods.__count;
  lhs_methods = ((const struct __go_interface_method *)
		 lhs_interface->__methods.__values);

  /* This should not be called for an empty interface.  */
  __go_assert (lhs_method_count > 0);

  rhs_uncommon = rhs_descriptor->__uncommon;
  if (rhs_uncommon == NULL || rhs_uncommon->__methods.__count == 0)
    {
      struct __go_empty_interface panic_arg;

      if (may_fail)
	return NULL;

      runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection,
				     lhs_descriptor->__reflection,
				     lhs_methods[0].__name,
				     &panic_arg);
      __go_panic (panic_arg);
    }

  rhs_method_count = rhs_uncommon->__methods.__count;
  p_rhs_method = ((const struct __go_method *)
		  rhs_uncommon->__methods.__values);

  methods = NULL;

  for (i = 0; i < lhs_method_count; ++i)
    {
      const struct __go_interface_method *p_lhs_method;

      p_lhs_method = &lhs_methods[i];

      while (rhs_method_count > 0
	     && (!__go_ptr_strings_equal (p_lhs_method->__name,
					  p_rhs_method->__name)
		 || !__go_ptr_strings_equal (p_lhs_method->__pkg_path,
					     p_rhs_method->__pkg_path)))
	{
	  ++p_rhs_method;
	  --rhs_method_count;
	}

      if (rhs_method_count == 0
	  || !__go_type_descriptors_equal (p_lhs_method->__type,
					   p_rhs_method->__mtype))
	{
	  struct __go_empty_interface panic_arg;

	  if (methods != NULL)
	    __go_free (methods);

	  if (may_fail)
	    return NULL;

	  runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection,
					 lhs_descriptor->__reflection,
					 p_lhs_method->__name, &panic_arg);
	  __go_panic (panic_arg);
	}

      if (methods == NULL)
	{
	  methods = (const void **) __go_alloc ((lhs_method_count + 1)
						* sizeof (void *));

	  /* The first field in the method table is always the type of
	     the object.  */
	  methods[0] = rhs_descriptor;
	}

      methods[i + 1] = p_rhs_method->__function;
    }

  return methods;
}

/* This is called by the compiler to convert a value from one
   interface type to another.  */

void *
__go_convert_interface (const struct __go_type_descriptor *lhs_descriptor,
			const struct __go_type_descriptor *rhs_descriptor)
{
  return __go_convert_interface_2 (lhs_descriptor, rhs_descriptor, 0);
}
