// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.google.protobuf;

import com.google.protobuf.Descriptors.FieldDescriptor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


/**
 * Data structure which is populated with the locations of each field value parsed from the text.
 *
 * <p>The locations of primary fields values are retrieved by {@code getLocation} or
 * {@code getLocations}.  The locations of sub message values are within nested
 * {@code TextFormatParseInfoTree}s and are retrieve by {@getNestedTree} or {code @getNestedTrees}.
 *
 * <p>The {@code TextFormatParseInfoTree} is created by a Builder.
 */
public class TextFormatParseInfoTree {

  // Defines a mapping between each field's descriptor to the list of locations where
  // its value(s) were was encountered.
  private Map<FieldDescriptor, List<TextFormatParseLocation>> locationsFromField;

  // Defines a mapping between a field's descriptor to a list of TextFormatParseInfoTrees for
  // sub message location information.
  Map<FieldDescriptor, List<TextFormatParseInfoTree>> subtreesFromField;

  /**
   * Construct a {@code TextFormatParseInfoTree}.
   *
   * @param locationsFromField a map of fields to location in the source code
   * @param subtreeBuildersFromField a map of fields to parse tree location information builders
   */
  private TextFormatParseInfoTree(
      Map<FieldDescriptor, List<TextFormatParseLocation>> locationsFromField,
      Map<FieldDescriptor, List<TextFormatParseInfoTree.Builder>> subtreeBuildersFromField) {

    // The maps are unmodifiable.  The values in the maps are unmodifiable.
    Map<FieldDescriptor, List<TextFormatParseLocation>> locs =
        new HashMap<FieldDescriptor, List<TextFormatParseLocation>>();
    for (Entry<FieldDescriptor, List<TextFormatParseLocation>> kv : locationsFromField.entrySet()) {
      locs.put(kv.getKey(), Collections.unmodifiableList(kv.getValue()));
    }
    this.locationsFromField = Collections.unmodifiableMap(locs);

    Map<FieldDescriptor, List<TextFormatParseInfoTree>> subs =
        new HashMap<FieldDescriptor, List<TextFormatParseInfoTree>>();
    for (Entry<FieldDescriptor, List<Builder>> kv : subtreeBuildersFromField.entrySet()) {
      List<TextFormatParseInfoTree> submessagesOfField = new ArrayList<TextFormatParseInfoTree>();
      for (Builder subBuilder : kv.getValue()) {
        submessagesOfField.add(subBuilder.build());
      }
      subs.put(kv.getKey(), Collections.unmodifiableList(submessagesOfField));
    }
    this.subtreesFromField = Collections.unmodifiableMap(subs);
  }

 /**
  * Retrieve all the locations of a field.
  *
  * @param fieldDescriptor the the @{link FieldDescriptor} of the desired field
  * @return a list of the locations of values of the field.  If there are not values
  *         or the field doesn't exist, an empty list is returned.
  */
  public List<TextFormatParseLocation> getLocations(final FieldDescriptor fieldDescriptor) {
    List<TextFormatParseLocation> result = locationsFromField.get(fieldDescriptor);
    return (result == null) ? Collections.<TextFormatParseLocation>emptyList() : result;
  }

  /**
   * Get the location in the source of a field's value.
   *
   * <p>Returns the {@link TextFormatParseLocation} for index-th value of the field in the parsed
   * text.
   *
   * @param fieldDescriptor the @{link FieldDescriptor} of the desired field
   * @param index the index of the value.
   * @return the {@link TextFormatParseLocation} of the value
   * @throws IllegalArgumentException index is out of range
   */
  public TextFormatParseLocation getLocation(final FieldDescriptor fieldDescriptor, int index) {
    return getFromList(getLocations(fieldDescriptor), index, fieldDescriptor);
  }

  /**
   * Retrieve a list of all the location information trees for a sub message field.
   *
   * @param fieldDescriptor the @{link FieldDescriptor} of the desired field
   * @return A list of {@link TextFormatParseInfoTree}
   */
  public List<TextFormatParseInfoTree> getNestedTrees(final FieldDescriptor fieldDescriptor) {
    List<TextFormatParseInfoTree> result = subtreesFromField.get(fieldDescriptor);
    return result == null ? Collections.<TextFormatParseInfoTree>emptyList() : result;
  }

  /**
   * Returns the parse info tree for the given field, which must be a message type.
   *
   * @param fieldDescriptor the @{link FieldDescriptor} of the desired sub message
   * @param index the index of message value.
   * @return the {@code ParseInfoTree} of the message value. {@code null} is returned if the field
   *         doesn't exist or the index is out of range.
   * @throws IllegalArgumentException if index is out of range
   */
  public TextFormatParseInfoTree getNestedTree(final FieldDescriptor fieldDescriptor, int index) {
    return getFromList(getNestedTrees(fieldDescriptor), index, fieldDescriptor);
  }

  /**
   * Create a builder for a {@code ParseInfoTree}.
   *
   * @return the builder
   */
  public static Builder builder() {
    return new Builder();
  }

  private static <T> T getFromList(List<T> list, int index, FieldDescriptor fieldDescriptor) {
    if (index >= list.size() || index < 0)  {
      throw new IllegalArgumentException(String.format("Illegal index field: %s, index %d",
          fieldDescriptor == null ? "<null>" : fieldDescriptor.getName(), index));
    }
    return list.get(index);
  }

  /**
   * Builder for a {@link TextFormatParseInfoTree}.
   */
  public static class Builder {

    private Map<FieldDescriptor, List<TextFormatParseLocation>> locationsFromField;

    // Defines a mapping between a field's descriptor to a list of ParseInfoTrees builders for
    // sub message location information.
    private Map<FieldDescriptor, List<Builder>> subtreeBuildersFromField;

     /**
     * Create a root level {@ParseInfoTree} builder.
     */
    private Builder() {
      locationsFromField = new HashMap<FieldDescriptor, List<TextFormatParseLocation>>();
      subtreeBuildersFromField = new HashMap<FieldDescriptor, List<Builder>>();
    }

    /**
     * Record the starting location of a single value for a field.
     *
     * @param fieldDescriptor the field
     * @param location source code location information
     */
    public Builder setLocation(
        final FieldDescriptor fieldDescriptor, TextFormatParseLocation location) {
      List<TextFormatParseLocation> fieldLocations = locationsFromField.get(fieldDescriptor);
      if (fieldLocations == null) {
        fieldLocations = new ArrayList<TextFormatParseLocation>();
        locationsFromField.put(fieldDescriptor, fieldLocations);
      }
      fieldLocations.add(location);
      return this;
    }

    /**
     * Set for a sub message.
     *
     * <p>A new builder is created for a sub message. The builder that is returned is a new builder.
     * The return is <emph>not</emph> the invoked {@code builder.getBuilderForSubMessageField}.
     *
     * @param fieldDescriptor the field whose value is the submessage
     * @return a new Builder for the sub message
     */
    public Builder getBuilderForSubMessageField(final FieldDescriptor fieldDescriptor) {
      List<Builder> submessageBuilders = subtreeBuildersFromField.get(fieldDescriptor);
      if (submessageBuilders == null) {
        submessageBuilders = new ArrayList<Builder>();
        subtreeBuildersFromField.put(fieldDescriptor, submessageBuilders);
      }
      Builder subtreeBuilder = new Builder();
      submessageBuilders.add(subtreeBuilder);
      return subtreeBuilder;
    }

    /**
     * Build the {@code TextFormatParseInfoTree}.
     *
     * @return the {@code TextFormatParseInfoTree}
     */
    public TextFormatParseInfoTree build() {
      return new TextFormatParseInfoTree(locationsFromField, subtreeBuildersFromField);
    }
  }
}
