// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  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

syntax = "proto3";

package conformance;

option java_package = "com.google.protobuf.conformance";
option objc_class_prefix = "Conformance";

// This defines the conformance testing protocol.  This protocol exists between
// the conformance test suite itself and the code being tested.  For each test,
// the suite will send a ConformanceRequest message and expect a
// ConformanceResponse message.
//
// You can either run the tests in two different ways:
//
//   1. in-process (using the interface in conformance_test.h).
//
//   2. as a sub-process communicating over a pipe.  Information about how to
//      do this is in conformance_test_runner.cc.
//
// Pros/cons of the two approaches:
//
//   - running as a sub-process is much simpler for languages other than C/C++.
//
//   - running as a sub-process may be more tricky in unusual environments like
//     iOS apps, where fork/stdin/stdout are not available.

enum WireFormat {
  UNSPECIFIED = 0;
  PROTOBUF = 1;
  JSON = 2;
  JSPB = 3;  // Only used inside Google. Opensource testees just skip it.
  TEXT_FORMAT = 4;
}

enum TestCategory {
  UNSPECIFIED_TEST = 0;
  BINARY_TEST = 1;  // Test binary wire format.
  JSON_TEST = 2;    // Test json wire format.
  // Similar to JSON_TEST. However, during parsing json, testee should ignore
  // unknown fields. This feature is optional. Each implementation can decide
  // whether to support it.  See
  // https://developers.google.com/protocol-buffers/docs/proto3#json_options
  // for more detail.
  JSON_IGNORE_UNKNOWN_PARSING_TEST = 3;
  // Test jspb wire format. Only used inside Google. Opensource testees just
  // skip it.
  JSPB_TEST = 4;
  // Test text format. For cpp, java and python, testees can already deal with
  // this type. Testees of other languages can simply skip it.
  TEXT_FORMAT_TEST = 5;
}

// Meant to encapsulate all types of tests: successes, skips, failures, etc.
// Therefore, this may or may not have a failure message. Failure messages
// may be truncated for our failure lists.
message TestStatus {
  string name = 1;
  string failure_message = 2;
  // What an actual test name matched to in a failure list. Can be wildcarded or
  // an exact match without wildcards.
  string matched_name = 3;
}

// The conformance runner will request a list of failures as the first request.
// This will be known by message_type == "conformance.FailureSet", a conformance
// test should return a serialized FailureSet in protobuf_payload.
message FailureSet {
  repeated TestStatus test = 2;
  reserved 1;
}

// Represents a single test case's input.  The testee should:
//
//   1. parse this proto (which should always succeed)
//   2. parse the protobuf or JSON payload in "payload" (which may fail)
//   3. if the parse succeeded, serialize the message in the requested format.
message ConformanceRequest {
  // The payload (whether protobuf of JSON) is always for a
  // protobuf_test_messages.proto3.TestAllTypes proto (as defined in
  // src/google/protobuf/proto3_test_messages.proto).
  oneof payload {
    bytes protobuf_payload = 1;
    string json_payload = 2;
    // Only used inside Google.  Opensource testees just skip it.
    string jspb_payload = 7;
    string text_payload = 8;
  }

  // Which format should the testee serialize its message to?
  WireFormat requested_output_format = 3;

  // The full name for the test message to use; for the moment, either:
  // protobuf_test_messages.proto3.TestAllTypesProto3 or
  // protobuf_test_messages.proto2.TestAllTypesProto2 or
  // protobuf_test_messages.editions.proto2.TestAllTypesProto2 or
  // protobuf_test_messages.editions.proto3.TestAllTypesProto3 or
  // protobuf_test_messages.editions.TestAllTypesEdition2023 or
  // protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable.
  string message_type = 4;

  // Each test is given a specific test category. Some category may need
  // specific support in testee programs. Refer to the definition of
  // TestCategory for more information.
  TestCategory test_category = 5;

  // Specify details for how to encode jspb.
  JspbEncodingConfig jspb_encoding_options = 6;

  // This can be used in json and text format. If true, testee should print
  // unknown fields instead of ignore. This feature is optional.
  bool print_unknown_fields = 9;
}

// Represents a single test case's output.
message ConformanceResponse {
  oneof result {
    // This string should be set to indicate parsing failed.  The string can
    // provide more information about the parse error if it is available.
    //
    // Setting this string does not necessarily mean the testee failed the
    // test.  Some of the test cases are intentionally invalid input.
    string parse_error = 1;

    // If the input was successfully parsed but errors occurred when
    // serializing it to the requested output format, set the error message in
    // this field.
    string serialize_error = 6;

    // This should be set if the test program timed out.  The string should
    // provide more information about what the child process was doing when it
    // was killed.
    string timeout_error = 9;

    // This should be set if some other error occurred.  This will always
    // indicate that the test failed.  The string can provide more information
    // about the failure.
    string runtime_error = 2;

    // If the input was successfully parsed and the requested output was
    // protobuf, serialize it to protobuf and set it in this field.
    bytes protobuf_payload = 3;

    // If the input was successfully parsed and the requested output was JSON,
    // serialize to JSON and set it in this field.
    string json_payload = 4;

    // For when the testee skipped the test, likely because a certain feature
    // wasn't supported, like JSON input/output.
    string skipped = 5;

    // If the input was successfully parsed and the requested output was JSPB,
    // serialize to JSPB and set it in this field. JSPB is only used inside
    // Google. Opensource testees can just skip it.
    string jspb_payload = 7;

    // If the input was successfully parsed and the requested output was
    // TEXT_FORMAT, serialize to TEXT_FORMAT and set it in this field.
    string text_payload = 8;
  }
}

// Encoding options for jspb format.
message JspbEncodingConfig {
  // Encode the value field of Any as jspb array if true, otherwise binary.
  bool use_jspb_array_any_format = 1;
}
