// Copyright 2013-2015 Jason Leyba
//
// 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.

import "protobuf/descriptor.proto";

option java_package = "com.github.jsdossier.proto";
option java_multiple_files = true;

package dossier;

message SanitizedContent {
  oneof kind {
    // Indicates a field should be treated as a sanitized URI when
    // injected into a Soy template.
    bool uri = 1;

    // Indicates a field should be treated as sanitized HTML content when
    // injected into a Soy template.
    bool html = 2;
  }
}

extend google.protobuf.FieldOptions {
  optional SanitizedContent sanitized = 51230;
}


// Describes a documented source file.
message SourceFile {
  // The file's base name.
  required string base_name = 1;
  // The path to the file; may be relative to some unspecified directory.
  required string path = 2;
  // The individual lines in the file. Each line should not be HTML escaped.
  repeated string lines = 3;
}


// Describes the resources to include in a generated HTML page.
message Resources {
  // Paths to stylesheets to link to in the generated page.
  repeated string css = 1 [(sanitized).uri = true];
  // Paths to JavaScript files to include in the generated page's head.
  repeated string head_script = 2 [(sanitized).uri = true];
  // Paths to JavaScript files to include in the generated page after
  // the DOM has been defined.
  repeated string tail_script = 3 [(sanitized).uri = true];
}


// Describes a type to link to.
message TypeLink {
  // The link display text.
  required string text = 1;
  // The link href.
  required string href = 2 [(sanitized).uri = true];
}


// Defines a link to a symbol's definition in its rendered source file.
message SourceLink {
  // Path from the current file to the rendered source file.
  required string path = 1;
  // The line in the source file containing the symbol, if known.
  optional int32 line = 2;
}


// Represents a tokenized JSDoc comment string. Each token represents pre-formatted
// HTML, literal text, a link, or a link of literal text.
message Comment {

  message Token {
    oneof content {
      // The text content for this token; text should be escaped when rendered.
      string text = 1;

      // The pre-escaped html content for this token.
      string html = 6 [(sanitized).html = true];
    }

    // If set, this token will be rendered as a hyperlink.
    optional string href = 4 [(sanitized).uri = true];
  }

  // The tokens that comprise this comment.
  repeated Token token = 1;
}


// Describes a deprecation notice.
message Deprecation {
  optional string html = 1 [(sanitized).html = true];
}


// Describes a type/property's visibility.
enum Visibility {
  // The type is globally accessible.
  PUBLIC = 0;
  // The type may only be used by subclasses or other code in the same file.
  PROTECTED = 1;
  // The type may only be used by other code in the same file.
  PRIVATE = 2;
  // The type may only be used by subclasses, or other code in the same
  // package.
  PACKAGE = 3;
}


message Tags {
  optional bool is_const = 1;
  optional bool is_deprecated = 2;
  optional bool is_dict = 3;
  optional bool is_final = 4;
  optional bool is_interface = 5;
  optional bool is_module = 6;
  optional bool is_struct = 7;
}


// Describes the basic properties for a documented JavaScript property.
message BaseProperty {
  // The property's name; this should not be the fully qualified name.
  required string name = 1;

  // Link to the location in the source file where this property is defined.
  required SourceLink source = 2;

  // The property's block comment.
  required Comment description = 3;

  // Whether this property is deprecated.
  optional Deprecation deprecation = 4;
  optional Visibility visibility = 5 [default = PUBLIC];
  optional Tags tags = 6;

  // The class or interface that defines this property.
  optional Comment defined_by = 7;

  // Parent class that defines this property.
  optional Comment overrides = 8;

  // Interfaces that define this property.
  repeated Comment specified_by = 9;
}


// Describes a non-function JavaScript property.
message Property {
  required BaseProperty base = 1;
  // HTML snippet declaring the property type. May be omitted if the type is
  // unknown.
  optional Comment type = 2;
}


// Describes a function JavaScript property.
message Function {
  message Detail {
    optional string name = 1;
    optional Comment type = 2;
    optional Comment description = 3;
  }

  required BaseProperty base = 1;
  repeated string template_name = 2;
  optional bool is_constructor = 3 [default = false];
  repeated Detail parameter = 4;
  optional Detail return = 5;
  repeated Detail thrown = 6;
}


// Describes an enumeration.
message Enumeration {
  message Value {
    required string name = 1;
    optional Comment description = 2;
    optional Deprecation deprecation = 3;
  }

  required Comment type = 1;
  repeated Value value = 2;
  optional Visibility visibility = 3 [default = PUBLIC];
}

// Describes how to build the side index for a generated page.
message Index {
  // Defines the href from the current page to the main index.
  required string home = 1 [(sanitized).uri = true];

  // Whether to generate the global type section.
  optional bool include_types = 2;

  // Whether to generate the module type section.
  optional bool include_modules = 3;

  // Additional links to include in the navigation pane.
  repeated TypeLink links = 4;
}


// Describes a JavaScript type to generate documentation for. Each |JsType|
// message describes a class, enum, interface, or namespace.
message JsType {

  // Short description for a type defined when this |JsType|.
  message TypeSummary {
    required string name = 1;                           // The type name.
    required string href = 2 [(sanitized).uri = true];  // The hyperlink for the actual type.
    required Comment summary = 3;                       // The summary sentence for this type.
  }

  // Describes a typedef defined within this type.
  message TypeDef {
    required string name = 1;
    required Comment type = 2;
    required SourceLink source = 3;
    required Comment description = 4;
    optional Deprecation deprecation = 5;
    optional Visibility visibility = 6 [default = PUBLIC];
  }

  required string name = 1;
  required SourceLink source = 5;
  repeated TypeSummary nested = 6;
  required Comment description = 7;
  required Tags tags = 8;
  optional Deprecation deprecation = 9;
  repeated TypeDef type_def = 10;

  optional Enumeration enumeration = 11;

  repeated Function static_function = 12;
  repeated Property static_property = 13;

  // Describes the main function for this type. This is typically a class
  // constructor, but may also be the main function for a namespace (which
  // all other properties are hung off of).
  optional Function main_function = 14;

  // Instance methods for this type.
  repeated Function method = 15;

  // Instance properties for this type.
  repeated Property field = 16;

  // List of inherited types for a class. This should be empty if |is_class|
  // is false. Classes should be listed in order, with the root type first.
  repeated Comment extended_type = 18;

  // The interfaces implemented by a class/extended by an interface. This
  // list should be empty if |is_class| and |is_interface| are false.
  repeated Comment implemented_type = 19;

  repeated Property compiler_constant = 20;

  // Link to the module or namespace this type belongs to.
  message ParentLink {
    required TypeLink link = 1;
    optional bool is_module = 2;
  }
  optional ParentLink parent = 21;

  // Link to another type that this type is an alias of.
  optional TypeLink aliased_type = 22;
}



// Describes how to render a generic HTML page.
message HtmlRenderSpec {
  // The resources to include.
  required Resources resources = 1;
  // The page title.
  required string title = 2;
  // The page content, if any.
  optional Comment content = 3;
  // Navigation index.
  required Index index = 4;
}


// Describes how to render a source file.
message SourceFileRenderSpec {
  // The resources to include.
  required Resources resources = 1;
  // The file to render.
  required SourceFile file = 2;
  // Navigation index.
  required Index index = 3;
}


// Describes how to render documentation for a JavaScript type.
message JsTypeRenderSpec {
  // The type to generate documentation for.
  required JsType type = 1;
  // The resources to include.
  required Resources resources = 2;
  // Navigation index.
  required Index index = 3;
}
