To solve the given optimization problem, we first need to convert the natural language description into a symbolic representation. This involves defining variables, an objective function, and constraints based on the problem statement.

Let's denote:
- $x_1$ as the number of vanilla ice cream cones made.
- $x_2$ as the number of chocolate ice cream cones made.

The objective is to maximize profit. Given that the profit per cone of vanilla ice cream is $2 and the profit per cone of chocolate ice cream is $3, the objective function can be written as:
\[ \text{Maximize: } 2x_1 + 3x_2 \]

The constraints based on the problem description are:
1. The ice cream bar must make at least 20 cones of vanilla ice cream: $x_1 \geq 20$
2. It cannot make more than 50 cones of vanilla ice cream: $x_1 \leq 50$
3. It must make at least 25 cones of chocolate ice cream: $x_2 \geq 25$
4. It cannot make more than 60 cones of chocolate ice cream: $x_2 \leq 60$
5. In total, the ice cream bar can make at most 80 cones: $x_1 + x_2 \leq 80$

Also, since we're dealing with the number of cones, both $x_1$ and $x_2$ must be non-negative integers.

Thus, the symbolic representation in JSON format is:
```json
{
    'sym_variables': [('x1', 'vanilla ice cream cones'), ('x2', 'chocolate ice cream cones')],
    'objective_function': '2*x1 + 3*x2',
    'constraints': ['x1 >= 20', 'x1 <= 50', 'x2 >= 25', 'x2 <= 60', 'x1 + x2 <= 80']
}
```

Now, let's write the Gurobi code in Python to solve this optimization problem:
```python
from gurobipy import *

# Create a new model
model = Model("IceCreamOptimization")

# Define variables
x1 = model.addVar(lb=20, ub=50, vtype=GRB.INTEGER, name="vanilla_cones")
x2 = model.addVar(lb=25, ub=60, vtype=GRB.INTEGER, name="chocolate_cones")

# Set the objective function
model.setObjective(2*x1 + 3*x2, GRB.MAXIMIZE)

# Add constraints
model.addConstr(x1 + x2 <= 80, "total_cones_limit")

# Optimize model
model.optimize()

# Print solution
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Vanilla cones: {x1.x}")
    print(f"Chocolate cones: {x2.x}")
    print(f"Total profit: {model.objVal}")
else:
    print("No optimal solution found")
```