// Protocol Buffers - Google's data interchange format
// Copyright 2024 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "upb/text/internal/encode.h"

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>

#include "upb/base/descriptor_constants.h"
#include "upb/base/string_view.h"
#include "upb/lex/round_trip.h"
#include "upb/message/array.h"
#include "upb/message/message.h"
#include "upb/text/options.h"
#include "upb/wire/eps_copy_input_stream.h"
#include "upb/wire/reader.h"
#include "upb/wire/types.h"

// Must be last.
#include "upb/port/def.inc"

#define CHK(x)     \
  do {             \
    if (!(x)) {    \
      return NULL; \
    }              \
  } while (0)

/*
 * Unknown fields are printed by number.
 *
 * 1001: 123
 * 1002: "hello"
 * 1006: 0xdeadbeef
 * 1003: {
 *   1: 111
 * }
 */
const char* UPB_PRIVATE(_upb_TextEncode_Unknown)(txtenc* e, const char* ptr,
                                                 upb_EpsCopyInputStream* stream,
                                                 int groupnum) {
  // We are guaranteed that the unknown data is valid wire format, and will not
  // contain tag zero.
  uint32_t end_group = groupnum > 0
                           ? ((groupnum << kUpb_WireReader_WireTypeBits) |
                              kUpb_WireType_EndGroup)
                           : 0;

  while (!upb_EpsCopyInputStream_IsDone(stream, &ptr)) {
    uint32_t tag;
    CHK(ptr = upb_WireReader_ReadTag(ptr, &tag, stream));
    if (tag == end_group) return ptr;

    UPB_PRIVATE(_upb_TextEncode_Indent)(e);
    UPB_PRIVATE(_upb_TextEncode_Printf)
    (e, "%d: ", (int)upb_WireReader_GetFieldNumber(tag));

    switch (upb_WireReader_GetWireType(tag)) {
      case kUpb_WireType_Varint: {
        uint64_t val;
        CHK(ptr = upb_WireReader_ReadVarint(ptr, &val, stream));
        UPB_PRIVATE(_upb_TextEncode_Printf)(e, "%" PRIu64, val);
        break;
      }
      case kUpb_WireType_32Bit: {
        uint32_t val;
        ptr = upb_WireReader_ReadFixed32(ptr, &val, stream);
        UPB_PRIVATE(_upb_TextEncode_Printf)(e, "0x%08" PRIu32, val);
        break;
      }
      case kUpb_WireType_64Bit: {
        uint64_t val;
        ptr = upb_WireReader_ReadFixed64(ptr, &val, stream);
        UPB_PRIVATE(_upb_TextEncode_Printf)(e, "0x%016" PRIu64, val);
        break;
      }
      case kUpb_WireType_Delimited: {
        int size;
        char* start = e->ptr;
        size_t start_overflow = e->overflow;
        CHK(ptr = upb_WireReader_ReadSize(ptr, &size, stream));
        CHK(upb_EpsCopyInputStream_CheckDataSizeAvailable(stream, ptr, size));

        // Speculatively try to parse as message.
        UPB_PRIVATE(_upb_TextEncode_PutStr)(e, "{");
        UPB_PRIVATE(_upb_TextEncode_EndField)(e);

        // EpsCopyInputStream can't back up, so create a sub-stream for the
        // speculative parse.
        upb_EpsCopyInputStream sub_stream;
        const char* sub_ptr = upb_EpsCopyInputStream_GetAliasedPtr(stream, ptr);
        upb_EpsCopyInputStream_Init(&sub_stream, &sub_ptr, size, true);

        e->indent_depth++;
        if (UPB_PRIVATE(_upb_TextEncode_Unknown)(e, sub_ptr, &sub_stream, -1)) {
          ptr = upb_EpsCopyInputStream_Skip(stream, ptr, size);
          e->indent_depth--;
          UPB_PRIVATE(_upb_TextEncode_Indent)(e);
          UPB_PRIVATE(_upb_TextEncode_PutStr)(e, "}");
        } else {
          // Didn't work out, print as raw bytes.
          e->indent_depth--;
          e->ptr = start;
          e->overflow = start_overflow;
          const char* str = ptr;
          ptr = upb_EpsCopyInputStream_ReadString(stream, &str, size, NULL);
          UPB_ASSERT(ptr);
          UPB_PRIVATE(_upb_TextEncode_Bytes)
          (e, (upb_StringView){.data = str, .size = size});
        }
        break;
      }
      case kUpb_WireType_StartGroup:
        UPB_PRIVATE(_upb_TextEncode_PutStr)(e, "{");
        UPB_PRIVATE(_upb_TextEncode_EndField)(e);
        e->indent_depth++;
        CHK(ptr = UPB_PRIVATE(_upb_TextEncode_Unknown)(
                e, ptr, stream, upb_WireReader_GetFieldNumber(tag)));
        e->indent_depth--;
        UPB_PRIVATE(_upb_TextEncode_Indent)(e);
        UPB_PRIVATE(_upb_TextEncode_PutStr)(e, "}");
        break;
      default:
        return NULL;
    }
    UPB_PRIVATE(_upb_TextEncode_EndField)(e);
  }

  return end_group == 0 && !upb_EpsCopyInputStream_IsError(stream) ? ptr : NULL;
}

#undef CHK

void UPB_PRIVATE(_upb_TextEncode_ParseUnknown)(txtenc* e,
                                               const upb_Message* msg) {
  if ((e->options & UPB_TXTENC_SKIPUNKNOWN) != 0) return;

  uintptr_t iter = kUpb_Message_UnknownBegin;
  upb_StringView view;
  while (upb_Message_NextUnknown(msg, &view, &iter)) {
    char* start = e->ptr;
    upb_EpsCopyInputStream stream;
    upb_EpsCopyInputStream_Init(&stream, &view.data, view.size, true);
    if (!UPB_PRIVATE(_upb_TextEncode_Unknown)(e, view.data, &stream, -1)) {
      /* Unknown failed to parse, back up and don't print it at all. */
      e->ptr = start;
    }
  }
}

void UPB_PRIVATE(_upb_TextEncode_Scalar)(txtenc* e, upb_MessageValue val,
                                         upb_CType ctype) {
  switch (ctype) {
    case kUpb_CType_Bool:
      UPB_PRIVATE(_upb_TextEncode_PutStr)(e, val.bool_val ? "true" : "false");
      break;
    case kUpb_CType_Float: {
      char buf[32];
      _upb_EncodeRoundTripFloat(val.float_val, buf, sizeof(buf));
      UPB_PRIVATE(_upb_TextEncode_PutStr)(e, buf);
      break;
    }
    case kUpb_CType_Double: {
      char buf[32];
      _upb_EncodeRoundTripDouble(val.double_val, buf, sizeof(buf));
      UPB_PRIVATE(_upb_TextEncode_PutStr)(e, buf);
      break;
    }
    case kUpb_CType_Int32:
      UPB_PRIVATE(_upb_TextEncode_Printf)(e, "%" PRId32, val.int32_val);
      break;
    case kUpb_CType_UInt32:
      UPB_PRIVATE(_upb_TextEncode_Printf)(e, "%" PRIu32, val.uint32_val);
      break;
    case kUpb_CType_Int64:
      UPB_PRIVATE(_upb_TextEncode_Printf)(e, "%" PRId64, val.int64_val);
      break;
    case kUpb_CType_UInt64:
      UPB_PRIVATE(_upb_TextEncode_Printf)(e, "%" PRIu64, val.uint64_val);
      break;
    case kUpb_CType_String:
      UPB_PRIVATE(_upb_HardenedPrintString)
      (e, val.str_val.data, val.str_val.size);
      break;
    case kUpb_CType_Bytes:
      UPB_PRIVATE(_upb_TextEncode_Bytes)(e, val.str_val);
      break;
    case kUpb_CType_Enum:
      UPB_ASSERT(false);  // handled separately in each encoder
      break;
    default:
      UPB_UNREACHABLE();
  }
}
