// Copyright 2020-2026 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package buf.compiler.v1alpha1;

// A diagnostic report, consisting of `Diagnostics` and the `File`s they diagnose.
message Report {
  // A file involved in a diagnostic `Report`.
  message File {
    // The path to this file. Does not need to be meaningful as a file-system
    // path.
    string path = 1;

    // The textual contents of this file. Presumed to be UTF-8, although it need
    // not be.
    bytes text = 2;

    // TODO: Before bumping this proto package to v1, we should consider making
    // the following optimization. Currently, we ship the entire file regardless
    // of whether all of it is used by a diagnostic. Instead, we should add some
    // way to send only what's needed. Any of the following will do:
    //
    // 1. Truncate text to only include the parts used by the diagnostics, and
    //    include start_offset and start_line to compensate for deleting a
    //    prefix of the file.
    // 2. Add a `repeated Hunk` field that includes whatever hunks of the file
    //    are relevant, so that the file can be reconstructed (and filled with
    //    e.g. nulls to compensate).
    //
    // It is not immediately clear if this optimization is necessary, because
    // source code files are rarely beyond the order of kilobytes in size. 
  }

  repeated File files = 1;
  repeated Diagnostic diagnostics = 2;
}

// A diagnostic within a `Report`.
message Diagnostic {
  // A diagnostic level. This affects how (and whether) it is shown to users.
  enum Level {
    LEVEL_UNSPECIFIED = 0;
    LEVEL_ICE = 1;
    LEVEL_ERROR = 2;
    LEVEL_WARNING = 3;
    LEVEL_REMARK = 4;
  }

  // A file annotation within a `Diagnostic`. This corresponds to a single
  // span of source code in a `Report`'s file.
  message Annotation {
    // A message to show under this snippet. May be empty.
    string message = 1;

    // Whether this is a "primary" snippet, which is used for deciding whether or not
    // to mark the snippet with the same color as the overall diagnostic.
    bool primary = 2;

    // Whether this annotation wants to be on its own window, separate from
    // annotations that follow.
    bool page_break = 7;

    // The index of `Report.files` of the file this annotation is for.
    //
    // This is not a whole `Report.File` to help keep serialized reports slim. This
    // avoids neeidng to duplicate the whole text of the file one for every annotation.
    uint32 file = 3;

    // The start offset of the annotated snippet, in bytes.
    uint32 start = 4;
    // The end offset of the annotated snippet, in bytes.
    uint32 end = 5;

    repeated Edit edits = 6;
  }

  // Edit is an edit to suggest on an `Annotation`.
  //
  // A pure insertion is modeled by `start == end`.
  // A pure deletion is modeled by empty `replace`.
  message Edit {
    // The start offset of the edit, relative to the containing snippet.
    uint32 start = 1;
    // The end offset of the edit, relative to the containing snippet.
    uint32 end = 2;

    // The text to insert in place of the selected region.
    string replace = 3;
  }

  // Required. The message to show for this diagnostic. This should fit on one line.
  string message = 1;

  // An optional machine-readable tag for the diagnostic.
  string tag = 8;

  // Required. The level for this diagnostic.
  Level level = 2;

  // An optional path to show in the diagnostic, if it has no annotations.
  // This is useful for e.g. diagnostics that would have no spans.
  string in_file = 3;

  // Annotations for source code relevant to this diagnostic.
  repeated Annotation annotations = 4;

  // Notes about the error to show to the user. May span multiple lines.
  repeated string notes = 5;
  // Helpful suggestions to the user.
  repeated string help = 6;

  // Debugging information related to the diagnostic. This should only be
  // used for information about debugging a tool or compiler that emits the
  // diagnostic, not the code being diagnosed.
  repeated string debug = 7;
}
