/* { dg-do compile } */

typedef unsigned _GCC_ATTR_ALIGN_u32t;
typedef _GCC_ATTR_ALIGN_u32t _Uint32t __attribute__ ((__aligned__ (4)));
typedef unsigned int _GCC_ATTR_ALIGN_u8t __attribute__ ((__mode__ (__QI__)));
typedef _GCC_ATTR_ALIGN_u8t _Uint8t __attribute__ ((__aligned__ (1)));
typedef unsigned _Sizet;
typedef _Sizet size_t;
typedef _Uint8t uint8_t;
typedef _Uint32t uint32_t;
typedef enum
{
  PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_LABEL_OPTIONAL,
    PROTOBUF_C_LABEL_REPEATED
}
ProtobufCLabel;
typedef enum
{
  PROTOBUF_C_TYPE_INT32, PROTOBUF_C_TYPE_SINT32, PROTOBUF_C_TYPE_SFIXED32,
    PROTOBUF_C_TYPE_INT64, PROTOBUF_C_TYPE_SINT64, PROTOBUF_C_TYPE_SFIXED64,
    PROTOBUF_C_TYPE_UINT32, PROTOBUF_C_TYPE_FIXED32, PROTOBUF_C_TYPE_UINT64,
    PROTOBUF_C_TYPE_FIXED64, PROTOBUF_C_TYPE_FLOAT, PROTOBUF_C_TYPE_DOUBLE,
    PROTOBUF_C_TYPE_BOOL, PROTOBUF_C_TYPE_ENUM, PROTOBUF_C_TYPE_STRING,
    PROTOBUF_C_TYPE_BYTES, PROTOBUF_C_TYPE_MESSAGE,
}
ProtobufCType;
typedef struct _ProtobufCBinaryData ProtobufCBinaryData;
struct _ProtobufCBinaryData
{
  size_t len;
};
typedef struct _ProtobufCMessageDescriptor ProtobufCMessageDescriptor;
typedef struct _ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
typedef struct _ProtobufCMessage ProtobufCMessage;
struct _ProtobufCFieldDescriptor
{
  uint32_t id;
  ProtobufCLabel label;
  ProtobufCType type;
  unsigned offset;
};
struct _ProtobufCMessageDescriptor
{
  unsigned n_fields;
  const ProtobufCFieldDescriptor *fields;
};
struct _ProtobufCMessage
{
  const ProtobufCMessageDescriptor *descriptor;
};
typedef enum
{
  PROTOBUF_C_WIRE_TYPE_VARINT, PROTOBUF_C_WIRE_TYPE_64BIT,
    PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED, PROTOBUF_C_WIRE_TYPE_START_GROUP,
    PROTOBUF_C_WIRE_TYPE_END_GROUP, PROTOBUF_C_WIRE_TYPE_32BIT
}
ProtobufCWireType;
size_t tag_pack (uint32_t, uint8_t *);
size_t prefixed_message_pack (ProtobufCMessage *, uint8_t *);
static inline size_t
uint32_pack (uint32_t value, uint8_t * out)
{
  unsigned rv = 0;
  if (value >= 0x80)
    {
      if (value >= 0x80)
	{
	  value >>= 7;
	}
    }
  out[rv++] = value;
}

static inline size_t
binary_data_pack (const ProtobufCBinaryData * bd, uint8_t * out)
{
  size_t len = bd->len;
  size_t rv = uint32_pack (len, out);
  return rv + len;
}

static size_t
required_field_pack (const ProtobufCFieldDescriptor * field,
		     const void *member, uint8_t * out)
{
  size_t rv = tag_pack (field->id, out);
  switch (field->type)
    {
    case PROTOBUF_C_TYPE_BYTES:
      {
	const ProtobufCBinaryData *bd =
	  ((const ProtobufCBinaryData *) member);
	out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
	return rv + binary_data_pack (bd, out + rv);
      }
    case PROTOBUF_C_TYPE_MESSAGE:
      {
	out[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED;
	return rv +
	  prefixed_message_pack (*(ProtobufCMessage * const *) member,
				 out + rv);
      }
    }
}

size_t
protobuf_c_message_pack (const ProtobufCMessage * message, uint8_t * out)
{
  unsigned i;
  size_t rv = 0;
  for (i = 0; i < message->descriptor->n_fields; i++)
    {
      const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
      const void *member = ((const char *) message) + field->offset;
      if (field->label == PROTOBUF_C_LABEL_REQUIRED)
	rv += required_field_pack (field, member, out + rv);
    }
}
